Your trial has ended. Reactivate Greptile to resume code reviews.
ci: deploy from main via Alchemy (CloudflareStateStore)#121
What changed
- New
.github/workflows/deploy.yml: on push tomain(and manual dispatch), deploys all four apps in order — server, admin, storev2, agent — each via its ownbun run deploy. Serialized with adeploy-productionconcurrency group (cancel-in-progress: false) so production deploys never overlap. 20-minute timeout, Bun 1.3.0. apps/server,apps/admin,apps/storev2alchemy.run.ts: pass astateStoreto thealchemy(...)call that, only whenCIis set, usesCloudflareStateStoreso all three apps share Alchemy state in Cloudflare (KV) instead of the local.alchemyfilesystem. Locally (CIunset) behavior is unchanged (undefined→ default local store).apps/server/alchemy.run.ts: addedadopt: trueto theHyperdrive("pscale-db", ...)resource so the first CI run adopts the existing Hyperdrive config instead of trying to recreate it.
GitHub secrets to create
CLOUDFLARE_API_TOKEN— Cloudflare API token with edit on: Workers Scripts, Workers KV Storage, Workers R2 Storage, Durable Objects, Hyperdrive, Workers Routes, DNS; plus Account Settings: Read.CLOUDFLARE_ACCOUNT_ID— the target Cloudflare account ID.ALCHEMY_STATE_TOKEN— a new, stable secret value used byCloudflareStateStoreto authenticate to the shared state backend. Generate once and keep it stable across runs (rotating it orphans state).ALCHEMY_PASSWORD— MUST equal the existing localALCHEMY_PASSWORDused for current deploys. It encrypts/decrypts secret state; a different value cannot read existing state and will break adoption.DOTENV_PROD— the full verbatim contents of the local.env.prodfile (all prod env vars). The workflow writes this to.env.prodbefore install/deploy.
Required attended first run BEFORE merging
Do the first deploy locally with CI semantics, watching the log to confirm resources are ADOPTED, not recreated — especially the Hyperdrive (pscale-db) and the Durable-Object-backed workers (server's ProductSearchObject / TransferReconciliationObject). Recreating those would drop the DB binding / DO state.
| 1 | CI=1 \ |
| 2 | CLOUDFLARE_API_TOKEN=… \ |
| 3 | CLOUDFLARE_ACCOUNT_ID=… \ |
| 4 | ALCHEMY_STATE_TOKEN=… \ |
| 5 | ALCHEMY_PASSWORD=<existing local value> \ |
| 6 | bun run deploy |
Run it per app (apps/server, apps/admin, apps/storev2, apps/agent) and verify each resource logs as adopted. Only merge once the attended run is clean.
Note
The --stage prod naming in each app's deploy script is load-bearing — it determines the physical resource names (e.g. server-api-prod, custom domains, WorkerRef({ service: "server-api-${stage}" }) in storev2). Do not change the stage name; it must stay prod for the shared state and cross-app references to resolve.
Open in Devin Review
Note
Deploy server, admin, storev2, and agent from main via GitHub Actions using CloudflareStateStore
- Adds a deploy.yml GitHub Actions workflow that triggers on push to main and manual dispatch, running
bun run deployserially forapps/server,apps/admin,apps/storev2, andapps/agent. - Updates alchemy.run.ts, apps/admin/alchemy.run.ts, and apps/storev2/alchemy.run.ts to use
CloudflareStateStorewhenprocess.env.CIis set, keeping local behavior unchanged. - Enables
adopt: trueon thepscale-dbHyperdrive resource in the server app.
Macroscope summarized 48e597f.
Checks
Added 1 commit
- ci: deploy all apps from main via alchemy with shared cloudflare stateaf60529
Important
- 🔍 Trigger review
This repository does not receive automatic reviews because it has fewer than 10 stars.
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 0128843b-5276-4b11-8aa9-00f8a5c30852
✨ Finishing Touches
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Commit unit tests in branch
ci/alchemy-deploy
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands.
Deploying with Cloudflare Workers Cloudflare Workers
The latest updates on your project. Learn more about integrating Git with Workers.
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs | vit-backend | 48e597ff | Jul 07 2026, 10:48 AM |
Deploying with Cloudflare Workers Cloudflare Workers
The latest updates on your project. Learn more about integrating Git with Workers.
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs | vit-admin | 48e597ff | Jul 07 2026, 10:48 AM |
Added 1 commit
- ci: use existing ENV_PROD secret name06ff3f0
✅ Devin Review: No Issues Found
Devin Review analyzed this PR and found no bugs or issues to report.
Open in Devin ReviewBlocker discovered after this PR was opened: apps/server now depends on khaan-client: github:darjss/khaan-client (committed on redesign/sorbet-pop, will reach main when #118 merges) — a private repo. GitHub Actions' built-in GITHUB_TOKEN cannot read other private repos, so bun install --frozen-lockfile in this workflow will fail once that dep lands on main. Before merging (or right after), pick one: (a) add a PAT with repo:read on darjss/khaan-client as a secret and wire it for bun's github: resolution, (b) SSH deploy key + git+ssh:// spec, or (c) publish khaan-client to a registry (npm private or GitHub Packages). Also note bun.lock has no khaan-client entry yet — owner needs one authed bun install locally to lock it.
Blocker resolved: khaan-client repo is now public (secret-scanned first), so github:darjss/khaan-client resolves authless in CI — no PAT/deploy-key/publish needed. bun.lock entry is recorded in the sorbet-pop working tree and lands with the next commit batch there. This PR is unblocked once v2 merges and the attended first deploy is done.