/** * 将 target/release 下的可执行文件与 sidecar 资源打成 zip(便携分发,非安装包)。 * 在 `npm run tauri:build` 中于 `tauri build` 之后调用。 */ const fs = require("node:fs"); const path = require("node:path"); const { execSync } = require("node:child_process"); const RELEASE_VERSION_URL = "http://81.71.163.140:8001/api/setreleaseversion"; async function notifyReleaseVersion(version) { const res = await fetch(RELEASE_VERSION_URL, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ version }), }); const body = await res.text(); if (!res.ok) { throw new Error(`HTTP ${res.status}: ${body}`); } let parsed; try { parsed = JSON.parse(body); } catch { throw new Error(`响应不是 JSON: ${body}`); } if (parsed.ok === false) { throw new Error(parsed.message || "写入 releaseversion 失败"); } console.log(`已同步 releaseversion 到服务器: ${version}`); } const tauriDir = path.join(__dirname, ".."); const npmReleaseDir = path.join(tauriDir, "..", "..", "npmrelease"); const conf = JSON.parse( fs.readFileSync(path.join(tauriDir, "tauri.conf.json"), "utf8"), ); const { productName, version } = conf; const releaseDir = path.join(tauriDir, "target", "release"); const cargoName = "tauri-app"; const exeName = process.platform === "win32" ? `${cargoName}.exe` : cargoName; const platformTag = process.platform === "win32" ? "win" : process.platform === "darwin" ? "osx" : "linux"; const archTag = process.arch === "arm64" ? "arm64" : "x64"; const zipDir = path.join(releaseDir, "bundle", "zip"); const zipPath = path.join( zipDir, `${productName}_${version}_${archTag}-${platformTag}.zip`, ); const exePath = path.join(releaseDir, exeName); if (!fs.existsSync(exePath)) { console.error(`未找到可执行文件: ${exePath},请先执行 tauri build`); process.exit(1); } const stagingRoot = path.join(releaseDir, "bundle", "_portable_staging"); const stageDir = path.join(stagingRoot, productName); fs.rmSync(stagingRoot, { recursive: true, force: true }); fs.mkdirSync(stageDir, { recursive: true }); const stagedExe = process.platform === "win32" ? `${productName}.exe` : productName; fs.copyFileSync(exePath, path.join(stageDir, stagedExe)); function writeVersionSidecar(dir, baseName, ver) { const file = path.join(dir, `${baseName}.version`); fs.writeFileSync(file, `${ver}\n`, "utf8"); return file; } writeVersionSidecar(stageDir, productName, version); // 复制主程序到 npmrelease,供 npm publish 打包 if (process.platform === "win32") { fs.mkdirSync(npmReleaseDir, { recursive: true }); const npmReleaseExe = path.join(npmReleaseDir, stagedExe); fs.copyFileSync(exePath, npmReleaseExe); writeVersionSidecar(npmReleaseDir, productName, version); console.log(`已复制主程序到 npmrelease: ${npmReleaseExe}`); } else { console.warn("非 Windows 平台,跳过复制到 npmrelease"); } const updaterPath = path.join(releaseDir, "updater.exe"); if (process.platform === "win32" && fs.existsSync(updaterPath)) { fs.copyFileSync(updaterPath, path.join(stageDir, "updater.exe")); } for (const dir of ["resources", "binaries"]) { const src = path.join(releaseDir, dir); if (fs.existsSync(src)) { fs.cpSync(src, path.join(stageDir, dir), { recursive: true }); } } fs.mkdirSync(zipDir, { recursive: true }); if (fs.existsSync(zipPath)) { fs.unlinkSync(zipPath); } if (process.platform === "win32") { const psStage = stageDir.replace(/'/g, "''"); const psZip = zipPath.replace(/'/g, "''"); execSync( `powershell -NoProfile -Command "Compress-Archive -Path '${psStage}\\*' -DestinationPath '${psZip}' -Force"`, { stdio: "inherit" }, ); } else { execSync(`cd "${stageDir}" && zip -qr "${zipPath}" .`, { stdio: "inherit" }); } fs.rmSync(stagingRoot, { recursive: true, force: true }); for (const dir of ["msi", "nsis"]) { fs.rmSync(path.join(releaseDir, "bundle", dir), { recursive: true, force: true, }); } console.log(`便携压缩包已生成: ${zipPath}`); notifyReleaseVersion(version).catch((err) => { console.error(`同步 releaseversion 失败: ${err.message}`); process.exit(1); });