| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- import { cpSync, existsSync, mkdirSync, rmSync, statSync, writeFileSync, renameSync } from "node:fs"
- import { readFile } from "node:fs/promises"
- import { execSync } from "node:child_process"
- import { resolve } from "node:path"
- import { fileURLToPath } from "node:url"
- const root = resolve(dirname(fileURLToPath(import.meta.url)), "..")
- const pkg = JSON.parse(await readFile(resolve(root, "package.json"), "utf8"))
- let currentBranch = ""
- try {
- currentBranch = execSync("git rev-parse --abbrev-ref HEAD").toString().trim()
- } catch {}
- const isStorySimulationBranch = currentBranch === "feature-story-simulation"
- const releaseExe = resolve(root, "src-tauri/target/release/qmai.exe")
- const portableDevExe = resolve(root, "src-tauri/target/portable-dev/qmai.exe")
- const sourceExe = existsSync(portableDevExe) ? portableDevExe : releaseExe
- const outDir = resolve(root, "release-portable")
- const outExe = resolve(outDir, isStorySimulationBranch ? "QMaiWrite-剧情推演版.exe" : "QMaiWrite.exe")
- const outSkillDir = resolve(outDir, "skills")
- const manifest = resolve(outDir, "version-info.json")
- const backupDir = resolve(root, "release-portable-backup")
- if (!existsSync(sourceExe)) {
- throw new Error(`未找到最新 EXE,请先运行 npm run tauri build:${sourceExe}`)
- }
- // 尝试安全清理输出目录
- try {
- if (existsSync(backupDir)) {
- try {
- rmSync(backupDir, { recursive: true, force: true })
- } catch {}
- }
-
- if (existsSync(outDir)) {
- // 先尝试重命名而不是直接删除
- renameSync(outDir, backupDir)
- try {
- rmSync(backupDir, { recursive: true, force: true })
- } catch {}
- }
- } catch {}
- mkdirSync(outDir, { recursive: true })
- // 复制 exe,处理被占用的情况
- try {
- if (existsSync(outExe)) {
- const backupExe = resolve(outDir, "QMaiWrite-old.exe")
- try {
- if (existsSync(backupExe)) {
- rmSync(backupExe, { force: true })
- }
- renameSync(outExe, backupExe)
- } catch {}
- }
- cpSync(sourceExe, outExe)
- } catch (e) {
- console.warn("警告:无法完全替换正在运行的 exe,保留旧版本,但已更新其他资源")
- }
- // 复制 skills 文件夹到便携版目录
- const sourceSkillDir = resolve(root, "skills")
- if (existsSync(sourceSkillDir)) {
- try {
- rmSync(outSkillDir, { recursive: true, force: true })
- } catch {}
- mkdirSync(outSkillDir, { recursive: true })
- cpSync(sourceSkillDir, outSkillDir, { recursive: true })
- }
- const exeStat = statSync(outExe)
- writeFileSync(manifest, JSON.stringify({
- productName: isStorySimulationBranch ? "青幕AI写作(剧情推演版)" : "青幕AI写作",
- version: pkg.version,
- builtAt: new Date().toISOString(),
- sourceExe,
- portableExe: outExe,
- exeBytes: exeStat.size,
- includesSkills: existsSync(outSkillDir),
- ...(isStorySimulationBranch ? { variant: "story-simulation", branch: currentBranch } : {}),
- }, null, 2), "utf8")
- console.log(`便携版已生成:${outExe}`)
- console.log(`版本信息:${manifest}`)
- if (isStorySimulationBranch) {
- console.log("注意:这是测试版,不可上传到 GitHub main 分支")
- }
|