构建
一、产物关系(先搞清楚要发几样东西)
| 产物 | 文件名 | 作用 |
|---|---|---|
| Java 内核包 ×6 | java-llm-proxy_<版本>_{windows,linux,darwin}_{amd64,aarch64}.{zip,tar.gz} + .sha256 | 应用下载/内置的 Java 后端 |
| 桌面便携包 | LLMPoroxyUI-v<版本>-{Windows,Linux}-<arch>.{zip,tar.gz} | 用户直接解压运行 |
| 更新清单 | portable-update-windows.json / -linux.json / -darwin-v2.json | 应用内检查更新用 |
| (可选)Tauri 安装程序 | nsis .exe / msi .msi / dmg / deb / AppImage | 双击安装 |
三处版本号必须一致:pom.xml#L6、frontend/core-version.txt、frontend/src-tauri/Cargo.toml#L4(package_release.py 在带 --desktop 时会硬校验 Cargo 版本 == --version,不一致直接报错)。
二、发布步骤
第 0 步:版本号与更新说明
cd D:\code\java\project-litongjava\java-llm-proxy\frontend
node scripts/set-version.mjs 1.0.0 # 同步 Cargo.toml + Cargo.lock(失败自动回滚)
pom.xml 的 <version> 和 frontend/core-version.txt 手工改成同一版本。更新说明是可选的,放 frontend/docs/release-notes/v1.0.0/zh-CN.md、zh-TW.md、en.md、ja.md(规则见 frontend/docs/release-notes/README.md;缺哪个语言就提示"暂未提供",不做回退)。
第 1 步:构建
cd D:\code\java\project-litongjava\java-llm-proxy
mvn clean install '-DskipTests' '-Dgpg.skip'
mvn package '-DskipTests' '-Dgpg.skip' -Pproduction # 必须 -Pproduction,否则不是可执行的 fat jar
cd frontend
npm.cmd ci
npm.cmd run build # 前端静态资源
npm.cmd run tauri -- build # 正式 release 桌面程序(含安装包)
- 只要便携包、不要安装程序:
npm.cmd run tauri -- build --no-bundle;验收用的调试桌面程序:npm.cmd run tauri -- build --debug --no-bundle(readme 推荐)。 - 本机
frontend/src-tauri/target/release目前不存在,首次 release 打包会做完整编译;NSIS 和 WixTools314 已缓存在%LOCALAPPDATA%\tauri,不用重新下载。
第 2 步:生成发行产物(我已实测通过)
cd D:\code\java\project-litongjava\java-llm-proxy
python scripts\package_release.py --version 1.0.0 --jar target\java-llm-proxy-1.0.0.jar --desktop windows-amd64=frontend\src-tauri\target\release\cpa-gui.exe --output target\release-review
该脚本只落文件、不联网也不上传(结尾打印 no files were uploaded),并会校验 jar 有 Main-Class 和 LLMProxyApp.class。实测输出在 target/release-review:
java-llm-proxy_1.0.0_{windows,linux,darwin}_{amd64,aarch64}.{zip,tar.gz} # 每个约 26.8 MB
+ 同名 .sha256
LLMPoroxyUI-v1.0.0-Windows-amd64.zip (39.5 MB) + .sha256
portable-update-windows.json
清单长这样(fallbackUrls 指向 GitCode 镜像):
{ "schemaVersion": 1, "version": "1.0.0", "releaseUrl": ".../releases/tag/v1.0.0",
"releaseNotes": {}, "assets": { "windows-amd64": { "url": ".../LLMPoroxyUI-v1.0.0-Windows-amd64.zip",
"fallbackUrls": ["https://api.gitcode.com/api/v5/repos/ppnt/java-llm-proxy/releases/v1.0.0/attach_files/.../download"],
"sha256": "253fed27…", "sizeBytes": 41421106 } } }
注意三点:只传一个 --desktop 平台就只生成该平台的清单;macOS 会被拒绝(提示用 Tauri DMG);releaseNotes 恒为 {}——要带多语言说明得改用 Node 侧 frontend/scripts/release-notes.mjs + frontend/scripts/manifest.mjs --release-notes <json> 重新生成清单。
第 3 步:本地验收安装流程(我已实测 PASS)
python scripts\portable_package_test.py
# PASS: portable SHA-256, extraction, visible desktop launch, automatic JAR installation and authenticated Java management API
它会校验收到的 zip 的 SHA-256、解压到临时目录、启动 LLMPoroxyUI.exe,然后断言 cpa-core/java-llm-proxy.jar 被自动装好且带 token 的管理接口可用。留下的解压目录 target/portable-review-a7j2f6vp 就是安装后的真实布局,可以直接对照:
LLMPoroxyUI-v1.0.0-Windows-amd64\
LLMPoroxyUI.exe portable-app.json core-version.txt config.toml
cpa-core\ java-llm-proxy.jar(由内置 zip 解出) java-llm-proxy_1.0.0_windows_amd64.zip
cpa-gui-meta.json cpa-gui-bundled-core-handled.txt config.yaml data\proxy.db logs\
oauth\logs\core-start-output.log usage-records\usage.db
第 4 步:上传到 Release
gh release create v1.0.0 --repo litongjava/java-llm-proxy --title v1.0.0 --notes-file release-body.md target\release-review\*.zip target\release-review\*.tar.gz `
target\release-review\*.sha256 target\release-review\*.json
- tag 必须是
v1.0.0形式且不要标成 pre-release:应用查的是/releases/latest和https://github.com/litongjava/java-llm-proxy/releases/latest/download/portable-update-windows.json(frontend/src-tauri/src/main.rs#L107-L124)。 - 六个内核包 + 各自
.sha256都要传:内核更新会去下<包名>.sha256做校验(core_runtime.rs#L1133)。内核包名格式在core_runtime.rs#L861,对不上就不会被识别。 - GitCode 镜像(
ppnt/java-llm-proxy)用于清单里的fallbackUrls和应用内"下载源自动切换"。注意本仓库当前 git remote 是 GitHub + Gitee,没有 GitCode remote,依赖镜像前先确认镜像仓库确实存在。 release-body.md可用cd frontend; node scripts/release-notes.mjs --tag v1.0.0 --output notes.json --body-output release-body.md生成(正文只出英文+简体中文)。
三、用户怎么安装
- 便携包(官方发行物,推荐):下载
LLMPoroxyUI-v1.0.0-Windows-amd64.zip→ 解压 → 双击LLMPoroxyUI.exe。首次启动自动从cpa-core/里的内置内核包解出java-llm-proxy.jar(我实测会打印"Automatically installed or upgraded to the CPA kernel version bundled with the application")。 - 前置依赖:本机必须装 Java 21——应用优先用
JAVA_HOME\bin\java.exe,没有就退回 PATH 里的java(core_runtime.rs#L1491-L1493)。这跟内核包里的 jar 不是一回事,不能省。 - Tauri 安装程序(可选):
npm.cmd run tauri -- build产出frontend/src-tauri/target/release/bundle/nsis/*.exe、bundle/msi/*.msi(Linux 是 deb/rpm/AppImage,macOS 是 dmg)。安装包内嵌resources/java-llm-proxy.jar(tauri.conf.json#L30+frontend/scripts/prepare-core.mjs),装完同样在首次启动落地内核。 - 升级:
- 桌面程序:只有带
portable-app.json且autoUpdate: true的便携版能原地自更新(校验 sha256 → updater helper 备份替换,app_update.rs#L210、#L819);安装版只在"版本管理"页提示并打开 Release 页面(frontend/src/pages/VersionManagementPage.tsx)。 - Java 内核:独立于桌面更新,应用查最新 release 里匹配
java-llm-proxy_<版本>_<系统>_<架构>.zip的资产,下载校验后替换 jar(core_runtime.rs#L141、#L707-L741)。所以改 Java 只需发内核包,桌面可以不动。
- 桌面程序:只有带
四、发布前检查清单
mvn test '-Dgpg.skip'
mvn package '-DskipTests' '-Dgpg.skip' -Pproduction
python scripts\backend_smoke_test.py
python scripts\protocol_matrix_test.py
python scripts\websocket_integration_test.py
python scripts\native_endpoint_test.py
cd frontend; npm.cmd run build
cd src-tauri; cargo test management_api::tests -- --nocapture
