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

View File

@@ -8,7 +8,7 @@ const root = path.resolve(__dirname, "../..");
const distDir = path.join(root, "template", "dist");
const templateDir = path.join(root, "template");
const ICON_PRIORITY = ["logo.png", "favicon.ico"];
const ICON_PRIORITY = ["logo.png", "logo.jpg", "logo.jpeg", "favicon.ico"];
function findIconSource(baseDir) {
for (const name of ICON_PRIORITY) {

View File

@@ -19,6 +19,17 @@ if (!jobId || !appNameZh || !appNameEn || !appIdentifier) {
process.exit(1);
}
function readAppVersion(jobId) {
const versionFile = path.join(root, "builds", jobId, "version.txt");
if (fs.existsSync(versionFile)) {
const fromFile = fs.readFileSync(versionFile, "utf8").trim();
if (fromFile) return fromFile;
}
const fromEnv = (process.env.APP_VERSION ?? "").trim();
return fromEnv || "1.0.0";
}
const appVersion = readAppVersion(jobId);
const zipPath = path.join(root, "builds", jobId, "site.zip");
const distDir = path.join(root, "template", "dist");
const confPath = path.join(root, "template", "src-tauri", "tauri.conf.json");
@@ -46,6 +57,15 @@ if (!fs.existsSync(indexPath)) {
process.exit(1);
}
const buildDir = path.join(root, "builds", jobId);
for (const iconName of ["logo.png", "logo.jpg", "logo.jpeg", "favicon.ico"]) {
const iconSrc = path.join(buildDir, iconName);
if (fs.existsSync(iconSrc)) {
fs.copyFileSync(iconSrc, path.join(distDir, iconName));
console.log(`Copied uploaded icon: builds/${jobId}/${iconName}`);
}
}
function toSafeBinaryName(name, fallback) {
const ascii = name.replace(/[^a-zA-Z0-9_-]+/g, "");
return (ascii || fallback).slice(0, 64);
@@ -57,7 +77,7 @@ function patchTauriConfig(filePath) {
conf.productName = appNameZh;
conf.mainBinaryName = safeBinaryName;
conf.identifier = appIdentifier;
conf.version = "1.0.0";
conf.version = appVersion;
if (conf.app?.windows?.[0]) {
conf.app.windows[0].title = appNameZh;
}

View File

@@ -28,6 +28,7 @@ env:
APP_NAME: ${{ inputs.app_name }}
APP_NAME_EN: ${{ inputs.app_name_en }}
APP_IDENTIFIER: ${{ inputs.app_identifier }}
APP_VERSION: ${{ inputs.app_version }}
NDK_VERSION: "27.2.12479018"
jobs:
@@ -176,7 +177,7 @@ jobs:
tag_name: build-${{ inputs.job_id }}
name: Web2App ${{ inputs.app_name }} (${{ inputs.job_id }})
body: |
Automated build for **${{ inputs.app_name }}** (English: `${{ inputs.app_name_en }}`, ID: `${{ inputs.app_identifier }}`).
Automated build for **${{ inputs.app_name }}** (English: `${{ inputs.app_name_en }}`, version: `${{ inputs.app_version }}`, ID: `${{ inputs.app_identifier }}`).
- Windows desktop installer/portable binary
- Android APK (signed for sideload install)