Skip to content

Quality Gates

51hhh edited this page Sep 16, 2026 · 1 revision

质量门禁

本地全量门禁

./scripts/ci-local.sh

依次执行:

  1. Rust fmt
  2. Rust check
  3. Rust clippy(--all-targets -- -D warnings)
  4. Rust test
  5. 锁文件安装(npm ci)
  6. TypeScript 类型检查
  7. Vitest
  8. DOM / Xvfb smoke
  9. Canvas 导出像素 smoke
  10. 主窗口布局像素 smoke
  11. 生产入口 checker
  12. Vite build

require_cmd 预检:cargo / npm / npx / xvfb-run 缺失时在第一步整体报错并指向环境搭建说明,不让某个步骤在中途以难以归因的方式失败。

跳过不等于通过

两个像素 smoke 都需要 firefox 加 ffmpeg 或 python3-pil 才能读取截图像素。缺少依赖时整步跳过,这不算通过。

门禁输出必须能区分「通过 / 失败 / 跳过」三种状态。把跳过计入通过数是本项目明确禁止的。

同理,AppImage 或安装包未构建时不能计入通过数。

常用单项命令

# 仅编译后端
cd src-tauri && cargo check --all-targets

# 后端测试
cd src-tauri && cargo test
cd src-tauri && cargo test <test_name>

# 格式化与 lint
cd src-tauri && cargo fmt
cd src-tauri && cargo clippy --all-targets -- -D warnings

# 性能基线(门禁只编译不运行)
cd src-tauri && cargo bench

# X11 剪贴板协议回归(需 xvfb / xauth / xclip)
./scripts/test-x11-clipboard.sh

布局 smoke 的一个实现约束

布局 smoke 直接用 ?raw 引入产品 index.html 的结构,而不是另写一份 fixture。

原因:headless Firefox 的 --screenshot 不等待顶层 await,异步 fixture 只会拍到空白页——测试会「通过」,但什么都没检查。

断言失败时把原因画进红色浮层,这样截图本身就是可读的失败报告。

同时需要负控制:旧的错误 CSS 必须让 fixture 精确变红。只有正向绿色不能证明 fixture 真的在检查那件事。

平台矩阵的边界

  • Linux 发布目标仅 deb / AppImage
  • Windows 产出 NSIS / MSI
  • macOS 产出 Intel / Apple Silicon 的 app / DMG
  • 公共 tauri.conf.json 不含平台专属 bundle,三平台覆盖配置分别生成
  • updater 签名由 release CI secret 生成

test-x11-clipboard.sh 只在 Linux 执行,Windows / macOS 跳过。

必须靠真实桌面验收的项目

以下情形无头环境和单元测试都覆盖不到,只能在真实桌面上验证。把它们写进「已验证」是本项目出过事故的地方:

项目 原因
多显示器混合缩放 单屏无头环境不触发逐屏建窗循环;GTK 主线程约束只在真实多屏路径上暴露
分数缩放下的显示清晰度 缓冲区缩放与真实缩放的差异需要真实合成器
Portal 首次授权、撤权 需要用户交互确认
桌面后端是否允许静默恢复 各桌面环境策略不同
全局快捷键在真实桌面的冲突 无法通用枚举其它应用的绑定
窗口摆放与置顶 Wayland 下位置由合成器决定

对无法通用枚举的情况(X11 与 Portal 的跨应用快捷键冲突),必须明确报告「无法检查」,而不是「无冲突」。

提交与文档约定

  • 代码注释、commit message、文档使用中文
  • 前端 UI 文本使用英文
  • 变更记录进 CHANGELOG.md
  • 本地工作区数据(研究、评估、任务记录)不进版本库

依赖 vendor 的门禁约定

工作区显式包含 vendored 依赖,但默认成员只有主程序,普通 cargo test 不运行依赖自己的测试。

上游默认单元测试标记 ignored,避免显式运行时意外访问真实桌面;会写入剪贴板的 doctest 改为 no_run(仍编译)。

构建与测试统一使用主项目的 Cargo.lock;vendored 目录里上游自带的锁文件仅作来源记录,不是门禁锁文件。

升级 vendored 依赖时必须逐项核对本地补丁涉及的每个边界,复跑对应门禁,再决定移除补丁还是重放补丁。

Clone this wiki locally