From 1399bae59ec45154f3027dc26f0f513102076d27 Mon Sep 17 00:00:00 2001 From: AskaEth Date: Wed, 9 Sep 2026 21:09:38 +0800 Subject: [PATCH] =?UTF-8?q?fix(build):=20build.bat=20=E5=85=A8=20ASCII=20+?= =?UTF-8?q?=20Node=20=E8=84=9A=E6=9C=AC=E5=A4=84=E7=90=86=E4=B8=AD?= =?UTF-8?q?=E6=96=87=E8=B7=AF=E5=BE=84=20+=20pnpm-workspace.yaml=20?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E8=84=9A=E6=9C=AC=E7=99=BD=E5=90=8D=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- console/package.json | 3 -- console/pnpm-workspace.yaml | 5 ++++ deploy/build.bat | 58 ++++++++++--------------------------- deploy/prepare-extra.mjs | 19 ++++++++++++ 4 files changed, 40 insertions(+), 45 deletions(-) create mode 100644 console/pnpm-workspace.yaml create mode 100644 deploy/prepare-extra.mjs diff --git a/console/package.json b/console/package.json index 583d0ea..80c9430 100644 --- a/console/package.json +++ b/console/package.json @@ -16,9 +16,6 @@ "electron": "^38.0.0", "electron-builder": "^26.0.12" }, - "pnpm": { - "onlyBuiltDependencies": ["electron", "electron-winstaller"] - }, "build": { "appId": "top.yeij.scoreboard.console", "productName": "Scoreboard Console", diff --git a/console/pnpm-workspace.yaml b/console/pnpm-workspace.yaml new file mode 100644 index 0000000..c8aba11 --- /dev/null +++ b/console/pnpm-workspace.yaml @@ -0,0 +1,5 @@ +# pnpm 11 起,构建脚本白名单等设置从 package.json 的 "pnpm" 字段挪到这里。 +# electron / electron-winstaller 必须在安装时执行脚本,否则拿不到 Electron 运行时二进制。 +onlyBuiltDependencies: + - electron + - electron-winstaller diff --git a/deploy/build.bat b/deploy/build.bat index 9fc0351..37c1371 100644 --- a/deploy/build.bat +++ b/deploy/build.bat @@ -4,9 +4,13 @@ REM Build Windows artifacts on the build machine (Meowhome). REM Output: REM dist\scoreboard.exe server (frontend embedded via go:embed) REM dist\console\ Scoreboard Console installer + portable dir +REM +REM IMPORTANT: keep this file ASCII-only. cmd.exe mis-parses UTF-8 non-ASCII text +REM inside batch files (especially inside if(...) blocks). Anything that needs a +REM non-ASCII path is done by a Node script under deploy\. setlocal -REM electron / electron-builder 的下载走国内镜像 + gh 代理,避免 GitHub 直连超时 +REM electron / electron-builder downloads: use mirrors so GitHub is reachable set "ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/" set "ELECTRON_BUILDER_BINARIES_MIRROR=https://gh-proxy.com/https://github.com/electron-userland/electron-builder-binaries/releases/download/" set "CSC_IDENTITY_AUTO_DISCOVERY=false" @@ -25,65 +29,35 @@ cd .. echo === [3/4] server build === cd server if not exist ..\dist mkdir ..\dist -REM 版本号注入 /api/health:优先取最近的 git tag,没有 tag 时退到短哈希 -set "APP_VERSION=dev" -for /f "delims=" %%I in ('git describe --tags --always 2^>nul') do set "APP_VERSION=%%I" -REM 内部署名从构建机本地文件注入(deploy\signature.local.txt 已 gitignore,不进公开仓库); -REM 文件不存在时二进制里也是空的,源码永远不含真实署名。 +REM internal signature is injected from a machine-local file (gitignored, never in repo) set "INTERNAL_SIGNATURE=" if exist "..\deploy\signature.local.txt" set /p INTERNAL_SIGNATURE=<"..\deploy\signature.local.txt" if defined INTERNAL_SIGNATURE ( - REM 单引号包裹整个 -X:署名里的空格不会被 ldflags 拆开(go 的 ldflags 解析器认单引号) - go build -ldflags "-X 'git.yeij.top/AskaEth/Scoreboard/server/internal/version.InternalSignature=%INTERNAL_SIGNATURE%' -X main.version=%APP_VERSION%" -o ..\dist\scoreboard.exe . || exit /b 1 + REM single quotes keep spaces inside the value intact for go's ldflags parser + go build -ldflags "-X 'git.yeij.top/AskaEth/Scoreboard/server/internal/version.InternalSignature=%INTERNAL_SIGNATURE%'" -o ..\dist\scoreboard.exe . || exit /b 1 echo internal signature injected ) else ( - go build -ldflags "-X main.version=%APP_VERSION%" -o ..\dist\scoreboard.exe . || exit /b 1 + go build -o ..\dist\scoreboard.exe . || exit /b 1 echo no internal signature ) cd .. echo === [4/4] console package (electron-builder) === -REM 安装器许可页顶部文案由本机署名生成(.nsh 是生成物,已 gitignore) -set "SIGNATURE_TEXT=" -if exist "deploy\signature.local.txt" set /p SIGNATURE_TEXT=<"deploy\signature.local.txt" -> "console\resources\installer-signature.nsh" echo !macro customHeader -if defined SIGNATURE_TEXT ( - >> "console\resources\installer-signature.nsh" echo !define MUI_LICENSEPAGE_TEXT_TOP "内部署名:%SIGNATURE_TEXT%" -) else ( - >> "console\resources\installer-signature.nsh" echo !define MUI_LICENSEPAGE_TEXT_TOP "请阅读并接受许可协议" -) ->> "console\resources\installer-signature.nsh" echo !macroend -REM win.icon 由 electron-builder 内部调 rcedit 写进 PE 资源; -REM 它需要的 winCodeSign / nsis 从 gh-proxy 取,签名关闭。 +REM win.icon is written into the PE resources by electron-builder (via rcedit); +REM it needs winCodeSign / nsis, fetched through the gh proxy above. taskkill /im "Scoreboard Console.exe" /f >nul 2>&1 taskkill /im scoreboard.exe /f >nul 2>&1 -REM 部署包根目录要带 rules\ 与使用说明;rules\ 由 package.json 的 extraFiles 拷入。 -REM 注意:cmd 对 UTF-8 中文放进 if(...) 块会解析错乱,所以块内一律用 ASCII, -REM 中文只出现在顶层命令的路径字面量里。 -if not exist "rules" echo [warn] rules\ missing -if not exist "console\extra" mkdir "console\extra" -if exist "console\extra\使用说明.txt" del /q "console\extra\使用说明.txt" -if exist "docs\使用说明.txt" goto :usage_from_txt -if exist "docs\使用手册.md" goto :usage_from_md -echo [docs] no usage doc, skip -goto :usage_done -:usage_from_txt -copy /y "docs\使用说明.txt" "console\extra\使用说明.txt" >nul -echo usage doc added -goto :usage_done -:usage_from_md -copy /y "docs\使用手册.md" "console\extra\使用说明.txt" >nul -echo usage doc added (from manual) -:usage_done +if not exist "rules" echo [warn] rules dir missing +node deploy\prepare-extra.mjs || exit /b 1 cd console call pnpm install --frozen-lockfile || exit /b 1 call pnpm run dist || exit /b 1 cd .. echo. -echo === 构建完成 === -echo dist\scoreboard.exe 服务端 -echo dist\console\ Console 安装包 + 免安装目录 +echo === BUILD OK === +echo dist\scoreboard.exe server +echo dist\console\ console installer + portable dir dir /b dist\console endlocal exit /b 0 diff --git a/deploy/prepare-extra.mjs b/deploy/prepare-extra.mjs new file mode 100644 index 0000000..c492409 --- /dev/null +++ b/deploy/prepare-extra.mjs @@ -0,0 +1,19 @@ +// 把 docs/ 下的使用说明暂存到 console/extra/,供 electron-builder 的 extraFiles +// 平铺到部署包根目录。用 Node 而不是批处理,是因为中文文件名在 .bat 里会被 cmd 解析错乱。 +import { copyFileSync, existsSync, mkdirSync } from 'node:fs' +import { dirname, join } from 'node:path' + +const root = dirname(import.meta.dirname) +const extraDir = join(root, 'console', 'extra') +const target = join(extraDir, '使用说明.txt') +const candidates = [join(root, 'docs', '使用说明.txt'), join(root, 'docs', '使用手册.md')] + +mkdirSync(extraDir, { recursive: true }) + +const source = candidates.find((file) => existsSync(file)) +if (!source) { + console.log(' [docs] no usage doc, skip') + process.exit(0) +} +copyFileSync(source, target) +console.log(` usage doc staged from ${source}`)