Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Tests

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: tests-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
name: Tests (${{ matrix.os }}, Node ${{ matrix.node }})
runs-on: ${{ matrix.os }}
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04, windows-2022]
node: ['22', '24']
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: ${{ matrix.node }}
cache: pnpm
- uses: astral-sh/setup-uv@d0d8abe699bfb85fec6de9f7adb5ae17292296ff # v6
with:
version: '0.12.17'
enable-cache: false
- name: Install Node dependencies
run: pnpm install --frozen-lockfile
- name: Install Python test environment
run: |
uv venv --python 3.12 .workbench/test-python
uv pip install --python .workbench/test-python 'memotalk-sdk==0.1.0'
uv run --no-project --python .workbench/test-python python -c \
'import os, sys; open(os.environ["GITHUB_ENV"], "a", encoding="utf-8").write("MEMOTALK_TEST_PYTHON=" + sys.executable + "\n")'
- name: Install ffmpeg (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install --yes ffmpeg
- name: Install ffmpeg (Windows)
if: runner.os == 'Windows'
run: choco install ffmpeg --yes --no-progress
- name: Run application and verification regression tests
run: pnpm test:ci
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,20 @@ Upgrading removes the old `sdk_dir` setting while preserving other path, recogni
Set the `MEMOTALK_TEST_PYTHON` environment variable to the path of a Python interpreter with `memotalk-sdk` installed before running them.
Without this variable, SDK integration tests are skipped; settings API and migration tests still run.

### CI

GitHub Actions runs `pnpm test:ci` on pull requests and pushes to `main`, using
Ubuntu and Windows with Node 22 and 24. It installs a persistent Python 3.12
environment with `memotalk-sdk==0.1.0`, plus uv, ffmpeg and ffprobe. The CI command
fails if these prerequisites are missing, then runs both the application tests
and the verification helper regressions (`pnpm test:verification`).
Windows also runs the WinRT import and offline TTS tests; those platform-specific
tests are skipped on Linux.

Floatboat compiler builds, browser acceptance, physical BLE devices and paid
ASR/LLM calls are not part of this workflow. They remain separate local
verification steps under `.claude/skills/verify-openminutes`.

## Project structure

```text
Expand Down
11 changes: 11 additions & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,17 @@ SDK 会自动安装 `bleak`;无需克隆 SDK 源码或配置 SDK 目录。
设置环境变量 `MEMOTALK_TEST_PYTHON` 为安装了 `memotalk-sdk` 的解释器路径后运行。
未设置时跳过 SDK 集成用例,设置接口与迁移测试仍会执行。

### CI

GitHub Actions 在 PR 和推送到 `main` 时运行 `pnpm test:ci`,覆盖 Ubuntu、Windows
以及 Node 22、24。工作流安装持久的 Python 3.12 环境、`memotalk-sdk==0.1.0`、
uv、ffmpeg 和 ffprobe。CI 命令先检查依赖,缺失即失败,再执行应用测试及验证工具
回归测试(`pnpm test:verification`)。Windows 还会运行 WinRT 导入和离线 TTS
测试;Linux 跳过这两项平台专属测试。

Floatboat 编译器构建、浏览器验收、真实 BLE 设备和付费 ASR/LLM 调用不属于这个
工作流,仍通过 `.claude/skills/verify-openminutes` 在本地单独验证。

## 目录结构

```text
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
"private": true,
"version": "0.1.0",
"type": "module",
"packageManager": "pnpm@10.28.2",
"scripts": {
"start": "node --enable-source-maps dist/server/index.mjs",
"test": "tsx --test tests/*.test.ts"
"test": "tsx --test tests/*.test.ts",
"test:verification": "node --test .claude/skills/verify-openminutes/scripts/*.test.mjs",
"test:ci": "node scripts/check-test-dependencies.mjs && pnpm test && pnpm test:verification"
},
"engines": {
"node": ">=22.16.0"
Expand Down
25 changes: 25 additions & 0 deletions scripts/check-test-dependencies.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { spawnSync } from 'node:child_process';

const python = process.env.MEMOTALK_TEST_PYTHON;
if (!python) {
console.error('MEMOTALK_TEST_PYTHON must point to a persistent Python environment with memotalk-sdk installed.');
process.exit(1);
}

const checks = [
['uv', ['--version']],
[process.env.FFMPEG_TEST_COMMAND ?? 'ffmpeg', ['-version']],
['ffmpeg', ['-version']],
['ffprobe', ['-version']],
['uv', ['run', '--no-project', '--python', python, 'python', '-c',
'import bleak; from memotalk import MemoTalkClient; from memotalk.fake import FakeMemoTalk, FakeTransport']],
];

for (const [command, args] of checks) {
const result = spawnSync(command, args, { encoding: 'utf8', windowsHide: true, timeout: 60_000 });
if (result.error || result.status !== 0) {
console.error(`${command}: ${result.error?.message ?? result.stderr} (exit ${result.status})`);
process.exit(1);
}
}
console.log('CI test dependencies are available.');
Loading