From 73fb4c8742037d6a09a5dd44b5775ca20560fa2c Mon Sep 17 00:00:00 2001 From: remy Date: Fri, 30 Oct 2026 17:17:40 +1000 Subject: [PATCH] ci: run application and verification tests on Linux and Windows --- .github/workflows/test.yml | 57 +++++++++++++++++++++++++++++ README.md | 14 +++++++ README.zh-CN.md | 11 ++++++ package.json | 5 ++- scripts/check-test-dependencies.mjs | 25 +++++++++++++ 5 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/test.yml create mode 100644 scripts/check-test-dependencies.mjs diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..a9434f7 --- /dev/null +++ b/.github/workflows/test.yml @@ -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 diff --git a/README.md b/README.md index 0b77235..87dc304 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/README.zh-CN.md b/README.zh-CN.md index 1d4ed7c..a5cff76 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -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 diff --git a/package.json b/package.json index ee9bae2..b2ed8f6 100644 --- a/package.json +++ b/package.json @@ -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" diff --git a/scripts/check-test-dependencies.mjs b/scripts/check-test-dependencies.mjs new file mode 100644 index 0000000..43672c4 --- /dev/null +++ b/scripts/check-test-dependencies.mjs @@ -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.');