Three new workflow steps turn the CF deploy into fully zero-touch for
the avatar/logo feature:
1. Ensure R2 bucket exists — `wrangler r2 bucket list --json` → create if
missing. Idempotent; prior deploys skip creation.
2. Enable managed public URL — `PUT /r2/buckets/.../domains/managed`
with {enabled:true}. CF returns the same pub-<hash>.r2.dev on every
call once enabled, so this is idempotent too. Then GET the domain
from the same endpoint and capture into step output.
3. Upsert `PUBLIC_IMAGES_URL` as a Worker secret via
`wrangler secret put`. Always overwritten to keep in sync with the
managed domain (which is stable but this is defensive).
Order: bucket/URL steps run BEFORE `wrangler deploy` so the binding
declared in wrangler.toml (new `[[r2_buckets]] binding = "PUBLIC_IMAGES"`)
references an existing bucket. The secret step runs AFTER deploy —
wrangler secret put requires the Worker to exist.
`wrangler.toml`: new `[[r2_buckets]]` for production and
`[[env.staging.r2_buckets]]` for the staging environment. Staging uses
a distinct bucket (`zpan-public-images-staging`) so preview deploys
don't mix objects into production.
README updated: `CLOUDFLARE_API_TOKEN` now requires
**R2 Storage: Edit** in addition to Workers Scripts + D1. The workflow
surfaces an actionable error message when this scope is missing.
User experience on a fresh fork: add the 2 GitHub secrets (ACCOUNT_ID
+ API_TOKEN with the 3 scopes), push. Workflow creates D1, creates R2,
enables public URL, migrates, builds, deploys, sets both BETTER_AUTH_SECRET
(random) and PUBLIC_IMAGES_URL (from R2). Avatars + org logos work
immediately — no trip to Admin → Storages required.
Non-CF deployments continue to require a user-added mode='public'
storage (no change to those paths).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Document the full setup flow based on E2E testing:
- Create bucket in RustFS console
- Register user (first user gets admin)
- Configure storage with correct endpoint
- Important note: endpoint must be browser-accessible
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add deploy.yml: auto-deploys latest upstream release tag on fork sync
- Support manual trigger with optional version override
- Auto-create D1 database, apply migrations, and set BETTER_AUTH_SECRET
- Only runs on forks (skipped on saltbo/zpan)
- Validate required secrets with clear error message
- Update README with fork + GitHub Actions deploy instructions
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add json/json-summary reporters to vitest config, upload coverage
to Codecov after test step in CI, and add coverage badge to README.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace Pages Functions with Workers entry (`workers/bootstrap.ts`)
- Add Deploy to Cloudflare button in README
- Integrate `@cloudflare/vite-plugin` for CF dev with HMR
- Integrate `@hono/vite-dev-server` for Node dev with HMR
- `npm run dev` now defaults to CF Workers mode
- Add `run_worker_first = ["/api/*"]` so static assets stay free
- Extract shared Node bootstrap (`server/bootstrap.ts`) for reuse
- Update all docs from Pages to Workers references
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove the Go v1 codebase (preserved in the v1 branch) and establish
the foundation for v2 — a complete rewrite in TypeScript (server) and
Rust (CLI/desktop). This commit includes the product roadmap (v2.0–v2.9),
technical architecture document, and updated project documentation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>