Adds isolated Convex-backed Vercel PR previews with shared local/preview seeding, preview-safe routing, and production guards.
9.5 KiB
summary
| summary |
|---|
| Maintainer deploy checklist: Convex backend, Vercel web app and PR previews, CLI npm release, and API routing. |
Deploy
This is a maintainer runbook for the ClawHub project. It is intentionally kept
under specs/ so it does not publish into the user-facing ClawHub docs tab.
ClawHub is two deployables:
- Web app (TanStack Start) -> typically Vercel.
- Convex backend -> Convex deployment (serves
/api/...routes).
1) Deploy Convex
From your local machine:
bunx convex env set APP_BUILD_SHA "$(git rev-parse HEAD)" --prod
bunx convex env set APP_DEPLOYED_AT "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" --prod
bunx convex deploy
Or use the GitHub Actions pipeline:
gh workflow run deploy.yml --repo openclaw/clawhub --ref main
Production deploy notes:
-
deploy.ymlis manual-only (workflow_dispatch). Merging tomaindoes not deploy. -
The workflow must be started from
main. -
The catalog-taxonomy digest and high-/medium-confidence classification rollout migrations were one-time production operations and are no longer part of the deploy checklist.
-
While
migrations:runCatalogMetadataCanonicalizationexists, backend deploys that include it require an operator to dry-run, explicitly apply, and verify both tracked migrations before inferred-topic and inferred-category compatibility can be removed:bunx convex run migrations:runCatalogMetadataCanonicalization '{"dryRun":true}' --prod bunx convex run migrations:runCatalogMetadataCanonicalization \ '{"dryRun":false,"confirm":"canonicalize-catalog-metadata"}' --prod bunx convex run --component migrations lib:getStatus --watch --prod -
Deploy targets:
full: deploy Convex, verify contract, wait for the matching Vercel production deploy, then run smoke testsbackend: deploy Convex, verify contract, then run smoke tests against current productionfrontend: wait for the Vercel production deploy for the selectedmainSHA, then run smoke tests
-
frontenddoes not callvercel deploydirectly yet. It relies on the existing Vercel Git-based production deploy for that SHA. -
The real deploy job uses the GitHub
Productionenvironment for deploy secrets, but it does not wait for a separate approval. -
Required
Productionenvironment secret:CONVEX_DEPLOY_KEY. -
Optional
Productionenvironment secret:PLAYWRIGHT_AUTH_STORAGE_STATE_JSONfor authenticated smoke coverage.
CLI npm release
The clawhub CLI package is released separately from the app deploy.
Only stable releases are supported here: vX.Y.Z.
Use the GitHub Actions workflow:
gh workflow run clawhub-cli-npm-release.yml \
--repo openclaw/clawhub \
--ref main \
-f tag=v0.11.0 \
-f preflight_only=true
Then rerun the same workflow from main with:
- the same
tag preflight_only=falsepreflight_run_id=<successful preflight run id>
CLI release notes:
- Real publishes are manual-only and require the workflow to be started from
main. - The publish job waits at the GitHub
npm-releaseenvironment for approval. - npm auth is handled through npm trusted publishing, not an
NPM_TOKEN. - npm trusted publisher must be configured for package
clawhubwith repositoryopenclaw/clawhub, workflowclawhub-cli-npm-release.yml, and environmentnpm-release. - After a successful npm publish, the workflow creates or updates the matching GitHub Release from the
CHANGELOG.mdsection and appends npm tarball/integrity proof.
If npm publish succeeds but GitHub Release creation needs repair, rerun the GitHub Release workflow without publishing to npm again:
gh workflow run clawhub-cli-github-release.yml \
--repo openclaw/clawhub \
--ref main \
-f tag=v0.11.0 \
-f preflight_run_id=<successful preflight run id> \
-f update_existing=false
If the original publish workflow failed after npm publish while creating the
GitHub Release, omit publish_run_id; the repair workflow accepts only
successful proof run ids.
Use update_existing=true only when intentionally replacing the body for an
existing GitHub Release.
That workflow assumes Vercel Git integration is enabled for this repo. It does
not run vercel deploy directly; frontend-related steps wait for the GitHub
commit status Vercel - clawhub for the selected SHA, then run smoke tests
against production.
Ensure Convex env is set (auth + embeddings):
AUTH_GITHUB_IDAUTH_GITHUB_SECRETCONVEX_SITE_URLJWT_PRIVATE_KEYJWKSOPENAI_API_KEYRESEND_API_KEYfor account-ban notification emailCLAWHUB_SECURITY_EMAIL_FROMfor the outbound From header, defaulting toClawHub Security <noreply@notifications.openclaw.ai>on the verified Resend domainCLAWHUB_NOREPLY_FROMfor guarded staff emails, defaulting toClawHub <noreply@notifications.openclaw.ai>on the verified Resend domainSITE_URL(your web app URL)- Optional webhook env (see
docs/webhook.md) - Recommended GitHub App env for authenticated GitHub API reads used by publish
gates:
GITHUB_APP_IDGITHUB_APP_INSTALLATION_IDGITHUB_APP_PRIVATE_KEY
- Optional fallback:
GITHUB_TOKEN(used when GitHub App auth is unavailable, and for arbitrary public repository lookups such as trusted-publisher setup)
Do not set TRUST_FORWARDED_IPS=true while the Convex *.convex.site HTTP
origin remains publicly reachable. That flag makes rate limits and download
metrics trust forwarded client IP headers, so it is only safe behind a
header-sanitizing edge that prevents direct origin requests.
2) Deploy web app (Vercel)
Set env vars:
VITE_CONVEX_URLVITE_CONVEX_SITE_URL(Convex "site" URL)CONVEX_SITE_URL(same value; used by auth provider config)SITE_URL(web app URL)VITE_APP_BUILD_SHA(set to the same commit SHA stamped into Convex)
Deploy order:
- Convex
- contract verify
- wait for Vercel production deploy for the same Git SHA
- smoke
Disposable PR previews
Vercel Preview builds use bun run build:vercel. The build entrypoint requires a
Convex Preview deploy key, recreates the branch's Convex preview with
--preview-create, builds the frontend with that deployment's URL, and runs the
same bun run seed pipeline used by local development against that preview name.
One-time setup:
- In the Convex project settings, generate a Preview deploy key.
- In the Vercel project, set
CONVEX_DEPLOY_KEYto that key for the Preview environment only. - In the Convex project default environment variables for Preview deployments,
set:
CLAWHUB_PREVIEW=1CLAWHUB_DISABLE_CRONS=1
- Do not copy production auth, email, webhook, scanner, worker, backup, or user-channel secrets into Preview defaults.
- Remove
CONVEX_DEPLOY_KEYfrom the Vercel Production environment if it exists. Production Convex deploys remain manual-only through.github/workflows/deploy.yml.
The shared seed command fails closed unless its target is local or an explicit preview name selected with a Convex Preview deploy key. It installs the committed public corpus plus the same synthetic clean, suspicious, and malicious presentation states used locally. Staging remains snapshot-backed and production is never seeded.
Preview browser traffic is public and read-only. Nitro rejects non-GET/HEAD
requests before proxying and adds X-ClawHub-Preview-Backend to proxied preview
responses so smoke proof can record the paired non-secret deployment name.
Authenticated write flows belong in the permanent test environment.
3) Route /api/* to Convex
Nitro handles /api/** and /v1/feeds/** through the environment-aware Convex
proxy in server/convexProxy.ts. The target comes from the build's
VITE_CONVEX_SITE_URL, or is derived from the paired VITE_CONVEX_URL. Those
build-time values are compiled into the Nitro server output so stale Vercel
runtime variables cannot redirect a Preview deployment to production.
Do not add a production deployment hostname back to vercel.json. Static
rewrites would make Vercel previews query production even when their Convex
client points at a disposable backend.
For self-hosting, set VITE_CONVEX_URL and optionally
VITE_CONVEX_SITE_URL to the intended deployment before building.
4) Registry discovery
The CLI can discover the API base from:
- explicit CLI/env override
- configured registry URL
- site URL registry metadata
Keep production rewrites and discovery metadata aligned before release.
Hosted feeds
Refresh the OpenClaw hosted plugin and skill feeds after the production Convex deployment has the catalog projections:
gh workflow run publish-catalog-feed.yml --repo openclaw/clawhub --ref main
The workflow stores both current feed snapshots in Convex and serves them
through /v1/feeds/plugins and /v1/feeds/skills with public edge-cache
validators. The unversioned /feeds/plugins and /feeds/skills paths redirect
to their versioned routes. Attach registry.openclaw.ai to the same Vercel
project before configuring OpenClaw's default feed URLs.
Production backend deploys publish an initial promotions snapshot after Convex
deploys. Active promotion changes then refresh the stored snapshot immediately,
schedule refreshes at launch and expiry boundaries, and use a six-hour cron as
an expiry backstop. The feed is served through /v1/feeds/promotions, with
/feeds/promotions redirecting to the versioned route.
5) Post-deploy checks
Run the contract verifier and smoke tests against production after deploy:
bun run verify:convex-contract -- --prod
PLAYWRIGHT_BASE_URL=https://clawhub.ai bunx playwright test e2e/menu-smoke.pw.test.ts e2e/upload-auth-smoke.pw.test.ts