發布包
每個版本包含三個程式,各自提供便攜包和安裝包:gproxy-*:CLI,內建 Web 控制台。gproxy-headless-*:不帶控制台的同一個 CLI,用於 CI 和小型伺服器,見無前端 CLI。gproxy-tauri-*:桌面與行動裝置應用,同樣內嵌控制台。
發布工作流還會發布 serverless 可執行檔案(
gproxy-serverless-linux-<arch>-musl,x86_64 和 aarch64)、Cloudflare Workers 包(gproxy-edge-cloudflare.zip),以及 GNU 和 musl 容器映像。應用包會生成託管在 GitHub 上的構建證明(attestation)。公開的發布附件只包括各個包、manifest.json 和 SHA256SUMS;單獨的校驗檔案和構建證明屬於 CI 內部輸入。
各平臺說明:
- Linux:CLI DEB 把
gproxy安裝到/usr/bin。GNU Linux 應用依賴發行版的 GTK 3 和 WebKitGTK 4.1。musl 構建面向 Alpine,只提供 APK,不提供 DEB。 - Android CLI:Termux DEB 安裝到
/data/data/com.termux/files/usr。Android CLI 使用distribution/termux/中的原始碼配方和固定版本的 Termux 官方構建器構建。DEB 和 ZIP 都依賴 Termux 的libc++、OpenSSL 和 CA 證書;ZIP 包含啟動指令碼、可執行檔案以及記錄安裝和更新方法的TERMUX.txt。這些構建禁用了自更新:用 APT 安裝新版 DEB,或在已啟用的軟體倉庫收錄後執行pkg upgrade gproxy。 - Android 應用:APK 使用
ANDROID_SIGNING_*secrets 簽名並驗證。每個應用的<target-triple>-tauri-apk條目寫入 Ed25519 簽名的更新清單,與 CLI ZIP 的更新分開。舊的服務包裝 APK 不再構建。 - Windows:CLI MSIX 使用 Partner Center 分配的獨立包身份
LeenHawk.GPROXYCLI,並提供控制台命令別名。應用依賴系統的 WebView2 Runtime。 - macOS:CLI DMG 包含可執行檔案和在終端中安裝的說明。應用 ZIP 保留桌面資源,macOS 版包含完整的
.app。構建只做 ad-hoc 簽名,尚未接入 Developer ID 簽名和公證。 - 鴻蒙:使用快取的工具鏈映像和固定版本的實驗性 Tauri 分支構建,其他平臺使用穩定版 Tauri。HAP 安裝前需要自行簽名,已在模擬器上驗證。已實現持續後臺執行,但能否生效取決於裝置、系統版本和授予的許可權;應用程序退出後代理隨之停止。
構建環境
需要 stable Rust(edition 2024)、Go、Clang、Node.js 22.12+(推薦 24 LTS)和 pnpm。Linux 桌面構建還需要webkit2gtk-4.1、gtk+-3.0、libsoup-3.0 開發包。其他平臺的工具鏈由發布工作流配置。
CLI 與控制台
在倉庫根目錄執行:pnpm --dir console build 會把構建好的控制台複製到 HTTP 宿主和 Tauri 宿主的嵌入目錄,之後的 Rust 構建會把它編譯進去。順序不能顛倒:只執行 Rust 構建的全新檢出沒有控制台資源,/console 會返回 404。如果要使用單獨構建的控制台,傳入 --console-path console/dist。
Cargo feature
gproxy crate 的預設 feature 集合是 channels,memory,fs,bundled-vocabulary,embedded-console,postgres,mysql。
只帶四個渠道、不帶外部資料庫驅動的精簡構建:
gproxy-serverless 二進位檔,需要啟用 postgres feature。
無前端 CLI
無前端 CLI 就是不啟用embedded-console 構建的 gproxy 二進位檔。它保留代理路由、管理 API、全部渠道、SQLite、PostgreSQL 和 MySQL 驅動、記憶體快取、本地檔案儲存和內建詞表,透過 CLI 或管理 API 配置。構建不需要 Node.js、pnpm 或桌面庫:
embedded-console 時,即使檢出目錄中已有構建好的控制台,也不會嵌入二進位檔。--console=false 還會關閉對外部控制台目錄的服務。自定義 feature 集合如果需要內嵌控制台,加上 embedded-console。
發布工作流獨立於控制台構建生成以下無前端包:
從 Releases 下載:開發通道選
nightly,beta 選 staging,穩定版選對應版本。無前端安裝的自更新會選擇對應的無前端包。
在 Android 的 Termux 中安裝並啟動:
gproxy 包提供同一個命令,安裝時會替換後者。如果使用 ZIP,先安裝執行庫,再把 ZIP 解壓到 Termux 主目錄下的某個目錄(Android 共享儲存中的檔案不能執行),然後在該目錄中執行:
gproxy.exe 代替 gproxy。Windows MSIX 的包身份為 LeenHawk.GPROXYHeadless,命令別名為 gproxy-headless.exe,不會替換 CLI 的 gproxy.exe。GPROXY Headless 也已上架 Microsoft Store(9ND7FQQMV566)。
桌面與行動裝置應用
構建控制台後執行:--workspace 會把它包含進來。
要在本地生成發布包,先構建控制台,再執行打包指令碼。pnpm --dir console build 已經會執行 sync-to-embed.mjs,再執行一次也沒有影響。
dist/release/。
Cloudflare Workers
在倉庫根目錄執行:worker-build 負責編譯和最佳化 WebAssembly 模組;check 用 Wrangler 做一次部署預演,不會發布。配置和執行限制見邊緣部署;構建帶自有渠道的 Worker 見新增渠道。
CI 執行的檢查
提交 PR 前請先在本地執行。CI 對每次改動都會執行,分為後端、桌面和 WebAssembly 三個任務。 後端(workspace 預設成員):net feature,而 mio 無法在該目標上編譯。
pnpm --dir console lint 包含翻譯一致性檢查(pnpm i18n:check)。修改 Rust DTO 後,執行 pnpm --dir console types 重新生成 TypeScript 型別。
發布
分支與更新通道
Release 工作流(.github/workflows/release.yml)在推送時發布:
dev開發新功能,推送後只發布到nightly(dev 更新通道)。main維護已發布的功能並修復 bug,推送後只發布到staging(beta 更新通道)。- 正式版本 tag 從
main建立,同時發布到 release 和 beta 通道,不會覆蓋 dev 通道。
dev 前執行 bash scripts/push-dev.sh。指令碼會獲取最新的 origin/main,把 dev rebase 到它上面,再以針對上一次已發布 dev 的顯式 --force-with-lease 推送。用 git config core.hooksPath .githooks 啟用本地推送檢查。
發布版本
在最新的main 之上執行 bash scripts/release.sh,其間只允許新增 chore(release): 提交。以下條件不滿足時指令碼會停止:
- tag 與 workspace 版本一致,且存在
release-notes/v<版本>.md; - 已跟蹤的工作區是乾淨的;
HEAD包含最新的origin/main,且其後的提交都是chore(release):提交。
pnpm update --latest 更新控制台的 npm 依賴,用 cargo upgrade 升級 Rust 登錄檔依賴約束(包括大版本和固定版本),再用 cargo update 重新整理 Cargo.lock。RSA/getrandom、JNI/Tauri、Codex reqwest 和 WebSocket 配置的相容橋接依賴保留上游要求的版本線,但相容版本仍會透過 cargo update 更新。需要先安裝輔助工具:cargo install cargo-edit --locked。如果重新整理改動了已跟蹤檔案,指令碼會在打 tag 之前停止:處理相容性變更,執行上面的檢查,提交併推送到 main,然後重新執行指令碼。預發布 tag 不執行依賴重新整理。
隨後指令碼建立 tag,並把 main 和 tag 在一次原子推送中推上去。tag 觸發的工作流發布 release 和 beta 通道,main 在該 tag 提交上的執行不發布任何內容。完成後用 scripts/push-dev.sh 推送 dev。
工作流負責構建各個包、生成簽名的更新清單並上傳附件。構建或簽名任一步失敗,發布就不完整。
版本 tag 還會執行 scripts/publish-crates.sh,把 MIT 授權的函式庫發布到 crates.io。其他 crate 透過 git 或路徑依賴使用,見嵌入核心庫。
簽名與商店提交
缺少簽名金鑰或 Store 身份變數時,打包會失敗。- 更新清單:使用 Ed25519 簽名,自更新在安裝前校驗。
- Android:APK 使用
ANDROID_SIGNING_*secrets 簽名。 - macOS:只做 ad-hoc 簽名。
- Windows:各包使用 Microsoft Store 的包身份。在
release環境中配置四個變數:MS_STORE_IDENTITY_NAME、MS_STORE_DISPLAY_NAME、MS_STORE_IDENTITY_PUBLISHER、MS_STORE_PUBLISHER_DISPLAY_NAME;CLI 使用對應的MS_STORE_CLI_*變數。Headless 的包身份和顯示名固定,Store 提交只需在共用的發布者變數之外再配置MS_STORE_HEADLESS_PRODUCT_ID。正式版保留兩種架構的 Store 提交包;設定MS_STORE_PUBLISH_ENABLED後,GitHub 發布成功會觸發 Store 提交流程。Store 提交包不簽名,由 Store 在分發時簽名。 - GitHub 上的 Windows 套件:發布套件不做程式碼簽章。版本附帶的 ZIP 和 MSIX 都沒有簽章,Windows 執行前可能會跳出警告,MSIX 需要開啟側載才能安裝。已簽章的版本只能從 Microsoft Store 取得,也可以用
winget install --source msstore安裝。WinGet 社群來源只接受已簽章的 MSIX,發布套件不簽章期間不會有新版本。