feat: migrate to Cloudflare Workers with icon and version upload

Replace Express/SQLite and web/ with frontend/, worker/, and wrangler deploy. Add optional app icon upload, date-based app_version, and build-app workflow input.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-29 13:30:05 +08:00
parent 0921e5f7a1
commit b69dfc4813
55 changed files with 3285 additions and 3411 deletions

157
README.md
View File

@@ -2,83 +2,111 @@
将已构建好的静态网页zip入口 `index.html`)转换为 **Windows 桌面应用****Android APK**。本仓库包含:
- `web/`:上传与构建状态页面
- `server/`Express API负责 zip 校验、GitHub 上传workflow 触发
- `frontend/`React + Vite 上传与构建状态页面(文档风格 UI
- `worker/`Cloudflare Worker APIzip 校验、GitHub 上传workflow 触发
- `template/`:最小 Tauri 2 壳CI 中注入用户静态资源后打包
- `.github/workflows/build-app.yml`:并行构建 Windows / Android 并发布 Release
## 架构
1. 用户在本地网站上传 zip
2. 后端校验 zip 后,通过 GitHub Contents API 上传到 `builds/{jobId}/site.zip`
3. 后端触发 `build-app.yml` workflow
1. 用户访问 Worker 托管的前端并上传 zip
2. Worker 校验 zip 后,通过 GitHub Contents API 上传到 `builds/{jobId}/site.zip`
3. Worker 触发 `build-app.yml` workflow
4. GitHub Actions 解压 zip 到 `template/dist/`,构建 Windows 与 Android
5. `finalize` job 创建 Release`build-{jobId}`并返回下载链接
5. `finalize` job 创建 Release`build-{jobId}`前端轮询并展示下载链接
本地/生产均由 **一个 Worker** 提供 `/api/*` 与静态资源(`wrangler deploy` 一键部署)。
## 前置条件
- Node.js 20+
- [Cloudflare 账号](https://dash.cloudflare.com/) 与 [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/)
- 一个 GitHub 仓库(建议名称 `Web2App`
- Personal Access Token权限至少包含
- `repo`
- `workflow`
- Personal Access Token权限至少包含`repo``workflow`
## 快速开始
## 快速开始(本地)
### 1. 初始化 GitHub 仓库
### 1. 安装依赖
```bash
git init
git add .
git commit -m "init web2app platform"
git branch -M main
git remote add origin https://github.com/<owner>/Web2App.git
git push -u origin main
npm install
```
### 2. 配置环境变量
### 2. 配置密钥
```bash
cp .env.example .env
cp .dev.vars.example .dev.vars
```
编辑 `.env`
编辑 `.dev.vars`Wrangler 本地开发自动加载)
```env
GITHUB_TOKEN=ghp_xxx
GITHUB_OWNER=your-github-username
GITHUB_REPO=Web2App
DEFAULT_BRANCH=main
PORT=3001
MAX_UPLOAD_MB=50
```
### 3. 安装依赖并启动
### 3. 初始化 D1本地
```bash
npm install
npm run db:migrate:local
```
### 4. 构建前端并启动
```bash
npm run build -w frontend
npm run dev
```
- 前端:<http://localhost:5173>
- 后端<http://localhost:3001>
- 前端开发服务器<http://localhost:5173>`/api` 代理到 Worker `8787`
- Worker<http://127.0.0.1:8787>
### 4. 上传测试
首次 `wrangler dev` 前需存在 `frontend/dist``npm run build -w frontend`)。
准备一个 zip根目录包含 `index.html`,也可使用 `examples/sample-site/` 打包:
### 5. 上传测试
准备一个 zip根目录包含 `index.html`,也可使用 `examples/sample-site/` 打包。
## 部署到 Cloudflare
### 1. 登录并创建 D1
```bash
cd examples/sample-site
powershell Compress-Archive -Path * -DestinationPath ../sample-site.zip -Force
wrangler login
wrangler d1 create web2app
```
在网页中填写应用名称并上传 zip
将命令输出的 `database_id` 写入根目录 `wrangler.toml` 中对应 `[[d1_databases]]` 条目(若 Wrangler 未自动写入)
```bash
npm run db:migrate:remote
```
### 2. 配置生产密钥
```bash
wrangler secret put GITHUB_TOKEN
```
`wrangler.toml``[vars]` 中设置 `GITHUB_OWNER``GITHUB_REPO`(或使用 `wrangler secret put` 存放全部变量)。
### 3. 一键部署
```bash
npm run deploy
```
等价于:构建 `frontend/dist``wrangler deploy`Worker API + 静态资源 + D1 绑定)。
## API
| 方法 | 路径 | 说明 |
|------|------|------|
| `POST` | `/api/builds` | `multipart/form-data`: `file`, `appNameZh`, `appNameEn`, 可选 `identifier` |
| `GET` | `/api/health` | 健康检查 |
| `POST` | `/api/builds` | `multipart/form-data`: `file`, `appNameZh`, `appNameEn`, `appVersion`(默认当天如 `2026.5.29`),可选 `identifier``icon`PNG/JPG/ICO |
| `GET` | `/api/builds/:id` | 查询构建状态与下载链接 |
| `GET` | `/api/builds` | 最近 20 条构建记录 |
@@ -88,7 +116,9 @@ powershell Compress-Archive -Path * -DestinationPath ../sample-site.zip -Force
- `job_id`
- `app_name`
- `app_name_en`
- `app_identifier`
- `app_version`
构建产物发布到 Release tag`build-{job_id}`
@@ -100,20 +130,10 @@ powershell Compress-Archive -Path * -DestinationPath ../sample-site.zip -Force
2. `favicon.ico`
3. 若都未找到,使用模板内置默认图标
找到后 CI 会执行 `tauri icon` 生成 Windows / Android 所需的多尺寸图标。
### Android 签名
### Android 签名与安装
- CI 先构建未签名 APK再用 `apksigner` **签名**,可直接侧载安装(不修改 Gradle 配置,避免构建失败)
- 未配置 Secrets 时workflow 会生成临时 CI 证书(密码 `web2app-ci`,仅适合 demo
- 生产环境建议在仓库 Settings → Secrets 配置:
| Secret | 说明 |
|--------|------|
| `ANDROID_KEYSTORE_BASE64` | `.jks` 文件 base64 |
| `ANDROID_KEYSTORE_PASSWORD` | keystore 密码 |
| `ANDROID_KEY_PASSWORD` | key 密码 |
| `ANDROID_KEY_ALIAS` | 别名,默认 `web2app` |
- CI 先构建未签名 APK再用 `apksigner` 签名
- 生产环境建议在仓库 Settings → Secrets 配置 `ANDROID_KEYSTORE_BASE64`
本地生成 keystore
@@ -121,54 +141,35 @@ powershell Compress-Archive -Path * -DestinationPath ../sample-site.zip -Force
bash scripts/generate-android-keystore.sh web2app-release.jks web2app
```
- 首次 Android 构建会在 CI 中执行 `tauri android init`
- Android 构建依赖 NDK / SDKworkflow 已预装常见组件
### 手动验证 workflow
在 GitHub 仓库 Actions 页选择 **Build App**,手动填写:
- `job_id`: 任意已上传目录名(需先存在 `builds/{job_id}/site.zip`
- `app_name`: 演示应用
- `app_name_en`: Demo App
- `app_identifier`: com.web2app.demo
## 本地数据
- SQLite`data/web2app.db`
- 上传临时文件:内存处理,不持久化到磁盘
## Demo 限制
- 无登录鉴权,仅适合本地/内网 demo
- GitHub Actions 有排队时间与额度限制
- 大 zip 会短暂占用仓库空间finalize 会尝试删除 `site.zip`
- 未配置自有证书时,各次 CI 构建可能使用不同签名,无法覆盖安装旧版 APK
## 目录结构
```
Web2App/
├── web/ # Vite + React 前端
├── server/ # Express 后端
├── frontend/ # React + Vite 前端
├── worker/ # Cloudflare Worker API + D1 migrations
├── wrangler.toml # 统一部署配置
├── template/ # Tauri 2 模板
├── .github/workflows/ # CI 构建
── examples/ # 示例静态站点
└── data/ # 本地 SQLite运行时生成
├── .github/workflows/ # CI 构建(未随 Worker 迁移改动)
── examples/ # 示例静态站点
```
## 常见问题
**`wrangler dev` 找不到静态资源**
- 运行 `npm run build -w frontend`
**workflow_dispatch 返回 404**
- 确认 workflow 文件已在默认分支
- 确认 workflow 已在默认分支
- 确认 `DEFAULT_BRANCH` 与仓库默认分支一致
**D1 表不存在**
- 本地:`npm run db:migrate:local`
- 远程:`npm run db:migrate:remote`
**Release 没有下载链接**
- 等待 `finalize` job 完成
- 检查 Windows / Android job 是否都成功
**zip 校验失败**
- 确保 `index.html` 在 zip 根目录,或仅套一层文件夹