feat(): 添加更新功能
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* 构建脚本 - 自动加载项目内置签名密钥后执行 tauri build
|
||||
*/
|
||||
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve, dirname } from "node:path";
|
||||
import { execSync } from "node:child_process";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const root = resolve(__dirname, "..");
|
||||
const keyPath = resolve(root, ".tauri/signing-key");
|
||||
|
||||
try {
|
||||
process.env.TAURI_SIGNING_PRIVATE_KEY = readFileSync(keyPath, "utf-8").trim();
|
||||
process.env.TAURI_SIGNING_PRIVATE_KEY_PASSWORD = "";
|
||||
} catch {
|
||||
console.error(`错误: 未找到签名密钥 ${keyPath}`);
|
||||
console.error("请运行: pnpm tauri signer generate -w .tauri/signing-key -p \"\" --ci");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
execSync("pnpm tauri build", { stdio: "inherit", cwd: root });
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* @file /scripts/bump-version.mjs
|
||||
* @description 统一更新 Tauri 项目版本号
|
||||
* @author tsl (randy1924@163.com)
|
||||
* @date 2026-03-23 10:23:42
|
||||
* @lastModified 2026-03-23 10:25:08
|
||||
* @lastModifiedBy tsl (randy1924@163.com)
|
||||
* @example node scripts/bump-version.mjs [patch|minor|major|x.y.z]
|
||||
* @default patch
|
||||
*/
|
||||
|
||||
import { readFileSync, writeFileSync } from "node:fs";
|
||||
import { resolve, dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const root = resolve(__dirname, "..");
|
||||
|
||||
// 读取当前版本
|
||||
function getCurrentVersion() {
|
||||
const pkg = JSON.parse(readFileSync(resolve(root, "package.json"), "utf-8"));
|
||||
return pkg.version;
|
||||
}
|
||||
|
||||
// 根据 bump 类型计算新版本
|
||||
function bumpVersion(current, type) {
|
||||
const parts = current.replace(/-.*$/, "").split(".").map(Number);
|
||||
switch (type) {
|
||||
case "major":
|
||||
return `${parts[0] + 1}.0.0`;
|
||||
case "minor":
|
||||
return `${parts[0]}.${parts[1] + 1}.0`;
|
||||
case "patch":
|
||||
return `${parts[0]}.${parts[1]}.${parts[2] + 1}`;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const arg = process.argv[2] || "patch";
|
||||
const BUMP_TYPES = ["patch", "minor", "major"];
|
||||
const current = getCurrentVersion();
|
||||
let version;
|
||||
|
||||
if (BUMP_TYPES.includes(arg)) {
|
||||
version = bumpVersion(current, arg);
|
||||
} else if (/^\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?$/.test(arg)) {
|
||||
version = arg;
|
||||
} else {
|
||||
console.error(`错误: 无效参数 "${arg}",应为 patch / minor / major 或 x.y.z 格式`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const files = [
|
||||
{
|
||||
path: "package.json",
|
||||
update(content) {
|
||||
const json = JSON.parse(content);
|
||||
const old = json.version;
|
||||
json.version = version;
|
||||
return { result: JSON.stringify(json, null, 2) + "\n", old };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "src-tauri/tauri.conf.json",
|
||||
update(content) {
|
||||
const json = JSON.parse(content);
|
||||
const old = json.version;
|
||||
json.version = version;
|
||||
return { result: JSON.stringify(json, null, 2) + "\n", old };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "src-tauri/Cargo.toml",
|
||||
update(content) {
|
||||
let old = "";
|
||||
let replaced = false;
|
||||
const result = content.replace(
|
||||
/^version\s*=\s*"([^"]*)"/m,
|
||||
(match, v) => {
|
||||
if (replaced) return match;
|
||||
replaced = true;
|
||||
old = v;
|
||||
return `version = "${version}"`;
|
||||
}
|
||||
);
|
||||
return { result, old };
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
console.log(`\n${current} → ${version} (${BUMP_TYPES.includes(arg) ? arg : "指定版本"})\n`);
|
||||
|
||||
for (const file of files) {
|
||||
const filePath = resolve(root, file.path);
|
||||
const content = readFileSync(filePath, "utf-8");
|
||||
const { result, old } = file.update(content);
|
||||
writeFileSync(filePath, result, "utf-8");
|
||||
console.log(` ✔ ${file.path} ${old} → ${version}`);
|
||||
}
|
||||
|
||||
console.log("\n全部更新完成!");
|
||||
console.log("提示: package-lock.json 和 Cargo.lock 会在下次 install/build 时自动同步\n");
|
||||
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* @file /scripts/publish.mjs
|
||||
* @description 构建后生成 update.json 并上传到远程服务器
|
||||
* @usage node scripts/publish.mjs [--notes "更新说明"]
|
||||
*
|
||||
* 前置条件:
|
||||
* 1. 已运行 `pnpm run tauri-build` 生成构建产物
|
||||
* 2. 远程服务器 SSH 可达(192.168.2.127:22)
|
||||
*/
|
||||
|
||||
import { readFileSync, writeFileSync, readdirSync, existsSync } from "node:fs";
|
||||
import { resolve, dirname, basename } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { execSync } from "node:child_process";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const root = resolve(__dirname, "..");
|
||||
|
||||
// ===== 配置 =====
|
||||
const REMOTE_USER = "root_test";
|
||||
const REMOTE_HOST = "192.168.2.127";
|
||||
const REMOTE_PORT = 22;
|
||||
const REMOTE_DIR = "/var/www/html/work-order-monitor";
|
||||
const BASE_URL = "http://web.nps.yunvip123.cn/work-order-monitor";
|
||||
|
||||
// ===== 解析参数 =====
|
||||
const args = process.argv.slice(2);
|
||||
let notes = "";
|
||||
const notesIdx = args.indexOf("--notes");
|
||||
if (notesIdx !== -1 && args[notesIdx + 1]) {
|
||||
notes = args[notesIdx + 1];
|
||||
}
|
||||
|
||||
// ===== 读取版本号 =====
|
||||
const pkg = JSON.parse(readFileSync(resolve(root, "package.json"), "utf-8"));
|
||||
const version = pkg.version;
|
||||
|
||||
// ===== 查找构建产物 =====
|
||||
const bundleDir = resolve(root, "src-tauri/target/release/bundle/nsis");
|
||||
|
||||
if (!existsSync(bundleDir)) {
|
||||
console.error(`错误: 未找到构建目录 ${bundleDir}`);
|
||||
console.error("请先运行: pnpm run tauri-build");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const files = readdirSync(bundleDir);
|
||||
const setupFile = files.find((f) => f.includes(version) && f.endsWith("-setup.exe"));
|
||||
const sigFile = files.find((f) => f.includes(version) && f.endsWith("-setup.exe.sig"));
|
||||
|
||||
if (!setupFile || !sigFile) {
|
||||
console.error(`错误: 未找到版本 ${version} 的 -setup.exe 或 -setup.exe.sig 文件`);
|
||||
console.error(`目录内容: ${files.join(", ")}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const setupPath = resolve(bundleDir, setupFile);
|
||||
const sigPath = resolve(bundleDir, sigFile);
|
||||
const signature = readFileSync(sigPath, "utf-8").trim();
|
||||
|
||||
console.log(`\n版本: ${version}`);
|
||||
console.log(`安装包: ${setupFile}`);
|
||||
console.log(`签名文件: ${sigFile}`);
|
||||
console.log(`签名: ${signature.substring(0, 40)}...`);
|
||||
|
||||
// ===== 生成 update.json =====
|
||||
const encodedFileName = encodeURIComponent(setupFile);
|
||||
const updateJson = {
|
||||
version,
|
||||
notes: notes || `v${version} 更新`,
|
||||
pub_date: new Date().toISOString(),
|
||||
platforms: {
|
||||
"windows-x86_64": {
|
||||
url: `${BASE_URL}/${encodedFileName}`,
|
||||
signature,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const updateJsonPath = resolve(bundleDir, "update.json");
|
||||
writeFileSync(updateJsonPath, JSON.stringify(updateJson, null, 2), "utf-8");
|
||||
console.log(`\nupdate.json 已生成`);
|
||||
console.log(JSON.stringify(updateJson, null, 2));
|
||||
|
||||
// ===== 上传到远程服务器 =====
|
||||
console.log(`\n正在上传到 ${REMOTE_HOST}:${REMOTE_DIR} ...`);
|
||||
|
||||
try {
|
||||
// 确保远程目录存在
|
||||
execSync(
|
||||
`ssh -p ${REMOTE_PORT} ${REMOTE_USER}@${REMOTE_HOST} "mkdir -p ${REMOTE_DIR}"`,
|
||||
{ stdio: "inherit" }
|
||||
);
|
||||
|
||||
// 上传安装包
|
||||
console.log(` 上传 ${setupFile} ...`);
|
||||
execSync(
|
||||
`scp -P ${REMOTE_PORT} "${setupPath}" ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}/`,
|
||||
{ stdio: "inherit" }
|
||||
);
|
||||
|
||||
// 上传 update.json
|
||||
console.log(` 上传 update.json ...`);
|
||||
execSync(
|
||||
`scp -P ${REMOTE_PORT} "${updateJsonPath}" ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}/`,
|
||||
{ stdio: "inherit" }
|
||||
);
|
||||
|
||||
console.log("\n全部上传完成!");
|
||||
console.log(`更新地址: ${BASE_URL}/update.json`);
|
||||
console.log(`下载地址: ${BASE_URL}/${encodedFileName}\n`);
|
||||
} catch (e) {
|
||||
console.error("\n上传失败:", e.message);
|
||||
console.error("请检查 SSH 连接是否正常,或手动上传以下文件:");
|
||||
console.error(` 1. ${setupPath}`);
|
||||
console.error(` 2. ${updateJsonPath}`);
|
||||
console.error(` → 目标: ${REMOTE_HOST}:${REMOTE_DIR}/`);
|
||||
process.exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user