chore: bump to 1.5.15, publish full package + hot update

- 版本号 1.5.14 → 1.5.15
- 新增 scripts/publish-full.js:一键上传完整包到 latest 与 v<version> release
- 清理未引用的 session_sync_enhanced.js 与临时 test-sync.js

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
mac
2026-07-16 19:50:33 +08:00
parent 02fb553c9e
commit 3f27682e78
5 changed files with 90 additions and 237 deletions
+86
View File
@@ -0,0 +1,86 @@
#!/usr/bin/env node
// publish-full.js —— 发布完整安装包到自建 gitea。
// 把 dist/ 下的 dmg/zip/blockmap/latest-*.yml 上传到:
// - latest release(electron-updater 自动更新目标,文件名固定,覆盖上传)
// - v<version> release(版本存档,供手动下载)
"use strict";
const fs = require("fs");
const os = require("os");
const path = require("path");
const { execFileSync } = require("child_process");
const ROOT = path.join(__dirname, "..");
const pkg = JSON.parse(fs.readFileSync(path.join(ROOT, "package.json"), "utf8"));
const version = pkg.version;
let token = process.env.GIT_TOKEN || "";
if (!token) {
try { token = fs.readFileSync(path.join(os.homedir(), ".tokendun-git-token"), "utf8").trim(); } catch {}
}
if (!token) { console.error("缺少 gitea token:设置 GIT_TOKEN 或写入 ~/.tokendun-git-token"); process.exit(1); }
const OWNER = "mhgmh", REPO = "codex-market-app";
const API = `https://up.tokendun.cc/api/v1/repos/${OWNER}/${REPO}`;
const DIST = path.join(ROOT, "dist");
// 要上传的产物:dmg/zip/blockmap + latest-mac.yml
const files = fs.readdirSync(DIST).filter((f) =>
/\.(dmg|zip)(\.blockmap)?$/.test(f) || /^latest.*\.yml$/.test(f)
);
if (!files.length) { console.error("dist/ 下没有可上传的产物"); process.exit(1); }
console.log(`待上传 ${files.length} 个文件:\n ` + files.join("\n "));
function api(method, urlPath, body) {
const args = ["-s", "-X", method, "-H", `Authorization: token ${token}`, `${API}${urlPath}`];
if (body !== undefined) { args.push("-H", "Content-Type: application/json", "-d", JSON.stringify(body)); }
return execFileSync("curl", args, { encoding: "utf8", maxBuffer: 64 * 1024 * 1024 });
}
function apiJson(method, urlPath, body) {
try { return JSON.parse(api(method, urlPath, body)); } catch { return null; }
}
// 确保 release 存在(按 tag 取,缺则建)
function ensureRelease(tag, name, prerelease) {
let rel = apiJson("GET", `/releases/tags/${encodeURIComponent(tag)}`);
if (!rel || !rel.id) {
console.log(`创建 release ${tag} …`);
rel = apiJson("POST", `/releases`, {
tag_name: tag, target_commitish: "main", name, body: `TD工具箱 ${version} 完整安装包`,
draft: false, prerelease: !!prerelease,
});
}
if (!rel || !rel.id) { console.error(`无法创建/获取 release ${tag}`); process.exit(1); }
return rel;
}
function uploadTo(rel, tag) {
// 删同名旧 asset,再上传
const existing = new Map((rel.assets || []).map((a) => [a.name, a.id]));
for (const name of files) {
if (existing.has(name)) {
api("DELETE", `/releases/${rel.id}/assets/${existing.get(name)}`);
console.log(` [${tag}] 删除旧 asset: ${name}`);
}
}
for (const name of files) {
const file = path.join(DIST, name);
const code = execFileSync("curl", ["-s", "-o", "/dev/null", "-w", "%{http_code}",
"-X", "POST", "-H", `Authorization: token ${token}`,
"-F", `attachment=@${file};type=application/octet-stream`,
`${API}/releases/${rel.id}/assets?name=${encodeURIComponent(name)}`],
{ encoding: "utf8", maxBuffer: 64 * 1024 * 1024 });
console.log(` [${tag}] 上传 ${name} → HTTP ${code}`);
if (code !== "201") { console.error(` 上传 ${name} 失败`); process.exit(1); }
}
}
// 1) latest release —— electron-updater 自动更新目标
const latest = ensureRelease("latest", "自动更新通道", true);
uploadTo(latest, "latest");
// 2) v<version> release —— 版本存档
const verRel = ensureRelease(`v${version}`, `TD工具箱 ${version}`, false);
uploadTo(verRel, `v${version}`);
console.log(`\n✅ 完整包 v${version} 已发布到 latest 与 v${version} 两个 release。`);
console.log(` 自动更新地址:https://update.tokendun.cc/${OWNER}/${REPO}/releases/download/latest`);