本文档说明 Undefined 当前仓库中的主要构建方式,包括:
- Python 包构建(
wheel/sdist) Undefined-webui管理控制台的本地开发与验证- 跨平台连接器
apps/undefined-console/的桌面端 / Android 构建 - 原生优先聊天客户端
apps/undefined-chat/的桌面端 / Android 构建 - 手动 GitHub Actions artifact 构建
- GitHub Release 工作流的发布矩阵
约定:
- 浏览器版管理入口仍然是
uv run Undefined-webui- 桌面端 / Android Console 是额外的连接器 / 容器,不替代
Undefined-webui- Undefined Chat 是 Runtime API 的原生聊天客户端,Runtime 仍是会话、历史、任务、附件和事件真源
- Release 工作流默认覆盖
Windows / macOS / Linux / Android,不包含iOS
- 推荐 Python:
3.12 - 支持范围:
3.11~3.13 - 推荐使用
uv
安装依赖:
uv sync --group dev -p 3.12
uv run playwright installrender.render_latex 使用 Python 依赖中的 matplotlib.mathtext 本地渲染常见数学公式,不需要系统 TeX、Playwright 或外部网络。复杂 TeX 环境和自定义宏可能不受支持。
HTML 和 Markdown 图片渲染需要 Playwright:
uv run playwright install渲染 BrowserContext 强制离线;外部图片、字体、样式和脚本不会加载,应改为内联资源。
如果需要构建跨平台 Console 或 Chat,请额外准备:
- Node.js:建议
22 - Rust stable
- Tauri v2 所需系统依赖
- Android 构建时还需要 Java 17、Android SDK / NDK
构建发行包:
uv build仅构建 wheel:
uv build --wheel常用本地校验:
uv run ruff check .
uv run ruff format --check .
uv run mypy .
uv run pytest tests/如果你修改了 res/、img/、config.toml.example 等打包资源,建议额外检查 wheel 内容是否齐全。
推荐直接运行:
uv run Undefined-webui这条命令会启动管理控制台。推荐工作流:
- 启动
Undefined-webui - 在浏览器中打开 WebUI
- 若
config.toml缺失,先由 WebUI 自动生成模板 - 在 WebUI 中补齐配置、保存并校验
- 直接点击启动 Bot
当前仓库中的 WebUI 静态资源直接由 Python 后端托管,不需要额外执行前端打包命令。
如果你修改了:
src/Undefined/webui/templates/src/Undefined/webui/static/js/src/Undefined/webui/static/css/
建议至少运行:
uv run pytest tests/test_webui_management_api.py -q
uv run ruff check src/Undefined/webui当前 App 的职责不是维护一套长期独立的第二后台,而是:
- 保存连接档案
- 使用一个 IP/域名 + 两个端口录入方式管理实例
- 测试 Management / Runtime 入口
- 自动尝试登录后打开真正的远程 WebUI
- 退出 WebUI 后回到主界面
跨平台 Console 位于:
apps/undefined-console/
Undefined Chat 位于:
apps/undefined-chat/
cd apps/undefined-console
npm installChat 使用同样的安装方式:
cd apps/undefined-chat
npm installnpm run devnpm run tauri:devnpm run tauri:build在部分较新的 Linux 发行版上,本地执行 npm run tauri:build 可能在 AppImage 阶段失败,常见表现是:
failed to run linuxdeploy- 或
strip无法处理.relr.dyn段
如果你本地遇到这个问题,可直接使用:
NO_STRIP=true npm run tauri:build或者使用仓库里补好的快捷脚本:
npm run tauri:build:no-strip如果你只想在本机先验证 Linux 安装包链路,也可以优先只打 deb:
npm run tauri:build:no-strip -- --bundles deb这个问题主要是本机 linuxdeploy / strip 工具链兼容性导致,不一定代表项目代码或 Tauri 配置有问题。
推荐使用仓库脚本统一检查环境、初始化生成工程、构建并收集产物:
uv run python scripts/build_native_apps.py check --targets android --android-abi arm64-v8a
uv run python scripts/build_native_apps.py build --product chat --targets android --android-abi arm64-v8a脚本只构建当前机器本地可构建的目标,不会自动安装 Android SDK、NDK 或 Rust target。缺少依赖时,check 和 build 会报告需要补齐的命令。
首次或 CI 环境中,先初始化 Android 项目:
npm run tauri:android:initUndefined Chat 的 tauri:android:init 会在 Tauri 生成 src-tauri/gen/android 后自动运行 scripts/prepare_tauri_android.py,向生成工程注入移动端 HTML 预览使用的 HtmlPreviewActivity 和 Android Keystore 安全存储使用的 SecretPlugin。src-tauri/gen/ 仍是生成目录,不提交到仓库。
构建 Android:
npm run tauri:android -- --apk当前仓库也保留了 debug APK 构建路径,便于在 CI 中稳定产出可安装 APK:
npm run tauri:android:debug -- --apk构建 Tauri 桌面端通常需要:
sudo apt-get update
sudo apt-get install -y \
libwebkit2gtk-4.1-dev \
libgtk-3-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
patchelf- 可构建
.dmg - 如需签名 / notarization,需额外配置 Apple 证书与 secrets
- 当前 Release workflow 预留了后续接入空间
- 可构建
.exe/.msi - 若后续需要代码签名,可在 CI 中继续补证书配置
需要:
- Java 17
- Android SDK
- Android NDK
- Rust Android targets
Release workflow 会分别为 Console 和 Chat 构建 arm64-v8a、armeabi-v7a、x86、x86_64 的签名 release APK。发布环境必须配置 ANDROID_KEYSTORE_BASE64、ANDROID_KEYSTORE_PASSWORD、ANDROID_KEY_ALIAS 和 ANDROID_KEY_PASSWORD;缺少任一 secret 时 Android 发布任务会失败。
WebUI、Console 和 Chat 统一使用 Biome 2.5.10。两个 App 的 package.json 固定该版本,锁文件与根目录及两个 App 的 biome.json schema 同步维护;使用 npm ci 安装锁定的工具版本。
Biome v2 通过 files.includes 表达检查范围和排除规则。两个 App 的 biome.json 设置 root: false,避免从仓库根目录执行检查时出现 nested root configuration 错误;同时使用 extends: [] 显式声明不继承根配置,并各自声明 formatter.indentStyle = "tab",因此 App 代码的格式与规则完全由本目录配置决定,根目录的 WebUI 规则(4 空格缩进、9 条关闭的 lint 规则)不会渗入 App 检查。root: false 只声明配置的嵌套关系,不代表继承根规则。WebUI 脚本仍由根配置的 files.includes 单独圈定,Console 的 npm run lint:webui 通过 --config-path ../../biome.json 显式使用根配置。后续升级应同时迁移三份配置并运行两个 App 的 npm run check,不能只修改 schema 版本号。迁移方式见 Biome v2 官方指南。
仓库内已提供可版本化维护的 git hooks:
.githooks/pre-commit
打 tag 前的版本一致性校验不在本地钩子中执行(git 没有
pre-tag事件),由 Release workflow 调用scripts/release_notes.py validate完成。
安装方式:
bash scripts/install_git_hooks.sh安装后:
pre-commit会继续执行 Python 的ruff + mypy- 当提交里包含
apps/undefined-console/、apps/undefined-chat/、src/Undefined/webui/static/js/、biome.json、CI workflow 相关改动时,还会额外执行对应 App 的:Biome检查TypeScript类型检查cargo fmt --checkcargo check
说明:如果本机还没安装 App 依赖,需要先执行:
cd apps/undefined-console
npm install
cd ../undefined-chat
npm install当前 tag 发布工作流位于:
.github/workflows/release.yml
触发条件:
- 推送 tag:
v*
工作流主要阶段:
verify-python:校验 tag、构建版本和CHANGELOG.md最新版本一致,并执行ruff、mypy、pytest、uv build。verify-native-app:分别对 Console 和 Chat 执行npm run check。build-tauri-desktop:分别构建 Console / Chat 的 Linux.AppImage/.deb、Windows.exe/.msi、macOS x64.dmg和 macOS arm64.dmg。build-tauri-android:分别构建 Console / Chat 的 Android.apk。build-docker/merge-docker:构建并发布 Docker 多架构镜像,详见下节。publish-release:汇总所有产物并上传 GitHub Release;Release notes 从CHANGELOG.md最新版本条目生成,不读取 tag 注释。publish-pypi:发布 Python 包到 PyPI。
本节面向镜像维护者。部署和使用步骤见 Docker 一键部署指南。
| 镜像 | 内容与版本 |
|---|---|
ghcr.io/<owner>/undefined-bot:v<版本> |
Undefined 本体,包含 Python 3.12、项目依赖、FFmpeg、Docker CLI 和 Playwright Chromium;版本与项目版本一致 |
ghcr.io/<owner>/undefined-lxmusic2api:<短sha> |
从 lxmusic2api 上游固定 commit 构建,使用该 commit 的短 SHA 作为 tag |
.github/workflows/release.yml 在推送 v* tag 时构建这两个镜像。build-docker 在原生 amd64 / arm64 runner 上分别构建并推送 digest,merge-docker 再合并为支持 linux/amd64 与 linux/arm64 的 manifest。镜像发布使用内置 GITHUB_TOKEN,packages: write 权限仅授予这两个 job,无需额外配置推送 secret。
该工作流没有 workflow_dispatch,旧 tag 不会自动补建镜像。需要本地构建时,在仓库根目录执行以下命令,并将 <owner> 与 <版本> 替换成部署时使用的镜像 owner 和当前项目版本:
docker build -f src/Undefined/deploy/templates/Dockerfile.bot -t 'ghcr.io/<owner>/undefined-bot:v<版本>' .镜像定义集中在 src/Undefined/deploy/images.py:
- 升级 lxmusic2api 时,更新
LXMUSIC2API_UPSTREAM_SHA为完整的 40 位 commit SHA,再发布新版本;CI 会构建对应镜像,部署脚本只在选中该服务时解析它。 - 升级 NapCat、SearXNG、Firecrawl 及依赖时,更新对应镜像引用并同步
PIN_VERIFIED_ON。其中playwright-service与nuq-postgres当前使用latest。 - 修改后运行
uv run pytest tests/test_deploy_catalog.py tests/test_deploy_generate.py tests/test_deploy_packaging.py,核对镜像引用、生成配置与打包资源。
拉取请求与 main / develop 推送会触发 .github/workflows/ci.yml,工作流级声明 permissions: contents: read 与并发取消(同一 ref 的新推送会取消旧运行),每个 job 都带 timeout-minutes:
quality-check(Python 3.12):ruff+ruff format --check+mypy+pytest tests/ --cov(覆盖率低于pyproject.toml的fail_under即失败)+uv build --wheel并校验 wheel 内含资源。该 job 会setup-node并执行npm ci --prefix tests/frontend,以便 WebUI 前端的 node 行为测试(用 jsdom 驱动真实 DOM)真正执行——缺这段安装时该文件的_require_env()会让用例直接失败(只有在本地非 CI 环境下才会 skip)。python-compat(3.11 / 3.13):pyproject.toml声明>=3.11,<3.14,因此两端边界各跑一次mypy与pytest。native-app-quality-check(Console / Chat 矩阵):npm run check。
依赖统一通过 uv sync --group dev 安装:dev 是唯一一份工具清单(含 pytest-cov 与 types-* 类型桩),不再维护与它重复的 ci 组或 [project.optional-dependencies]。
如果只想让 GitHub Actions 编译一次原生 App 并从 workflow run 页面手动下载产物,不创建 GitHub Release,也不发布 PyPI,可以使用:
.github/workflows/manual-native-artifacts.yml
触发方式:
workflow_dispatch
默认输入会构建 Undefined Chat:
- 桌面端:Linux
.AppImage/.deb、Windows.exe/.msi、macOS x64 / arm64.dmg - Android:
arm64-v8adebug APK
可选输入:
source_ref:要构建的分支、tag 或 SHA;留空时使用 Actions 页面选择的 ref。product:chat、console或all。build_desktop:是否构建桌面端。desktop_platform:all、linux、windows或macos。build_android_debug:是否构建 Android debug APK。android_abi:arm64-v8a、armeabi-v7a、x86、x86_64或all。
手动 artifact 工作流的边界:
- 不调用
gh release create。 - 不发布 Python 包到 PyPI。
- Android 只构建 debug APK,不需要配置 release keystore secrets。
- artifacts 通过
actions/upload-artifact上传到 workflow run,默认保留 14 天。
注意:GitHub 的 workflow_dispatch 手动入口通常要求 workflow 文件已存在于默认分支。若该文件只存在于 feature 分支,Actions 页面可能不会显示这个手动 workflow;将该 workflow 文件合入默认分支后,可在运行时通过 source_ref 指向任意待构建分支,例如 feature/chat-app。
面向普通用户的下载选择见 README — Release 下载速查;本节只记录构建和发布矩阵。部署 Bot 本身不需要下载 Console / Chat 客户端安装包。
每次正式 Release 计划上传:
- Python
wheelsdist
- Windows
Undefined-Console-*-windows-x64-setup.exeUndefined-Console-*-windows-x64.msiUndefined-Chat-*-windows-x64-setup.exeUndefined-Chat-*-windows-x64.msi
- Linux
Undefined-Console-*-linux-x64.AppImageUndefined-Console-*-linux-x64.debUndefined-Chat-*-linux-x64.AppImageUndefined-Chat-*-linux-x64.deb
- macOS
Undefined-Console-*-macos-x64.dmgUndefined-Console-*-macos-arm64.dmgUndefined-Chat-*-macos-x64.dmgUndefined-Chat-*-macos-arm64.dmg
- Android
Undefined-Console-*-android-*-release.apkUndefined-Chat-*-android-*-release.apk
iOS 当前不在发布矩阵内。
如果你准备发布一个版本,建议本地先按以下顺序自检:
uv sync --group dev -p 3.12
uv run ruff check .
uv run ruff format --check .
uv run mypy .
uv run pytest tests/ --cov
uv build如果本次改动涉及 App:
cd apps/undefined-console
npm install
npm run check # 代码检查与测试(lint/typecheck/test/cargo fmt/check/test,具体以 package.json 为准)
# 注意:npm run tauri:build 会自动执行 npm run build,无需手动构建前端
cd ../undefined-chat
npm install
npm run check # Biome、TypeScript、unit + e2e(jsdom)测试、cargo fmt/check/test如果本次改动涉及 Android 构建链:
uv run python scripts/build_native_apps.py check --targets android --android-abi arm64-v8a
uv run python scripts/build_native_apps.py build --product chat --targets android --android-abi arm64-v8a如需排查底层 Tauri Android 命令,可继续直接运行:
npm run tauri:android:init
npm run tauri:android:prepare:check # Undefined Chat 检查生成工程已包含 HtmlPreviewActivity/SecretPlugin
npm run tauri:android:debug -- --apk- 日常开发和首次部署,优先验证
uv run Undefined-webui全流程是否顺畅。 - 改动管理接口时,优先补
tests/test_webui_management_api.py。 - 改动发布矩阵时,务必同步更新
README.md、Undefined Chat 与本文件。 - 改动 App 构建脚本时,注意同时检查
apps/undefined-console/package.json、apps/undefined-chat/package.json与.github/workflows/release.yml。